Michael Miner
Michael Miner

Reputation: 964

C++ New Objects

I am learning C++ and I can not figure this out. I do not want to post all my code but feel that it is necessary as it is overall short.

#include <iostream>
#include "MathObject.h"
using namespace std;

int main(int args, char *argv[]){
    MathObject mo = new MathObject(3,4);
    int sum = mo.sum();

    cout << sum << endl;
    return 0;
}

#include <iostream>
#include "MathObject.h"
using namespace std;

MathObject :: MathObject(int n, int m){
   num1 = n;
   num2 = m;
}

int MathObject :: sum(){
    return num1+num2;
}

class MathObject{
private:
    int num1;
    int num2;

public:
    int sum();
    MathObject(int n, int m);
};

So this is all in 3 separate files, I am using an example from my prof as a template on how to make classes and header files to organize our code. This always returns the error:

  conversion from 'MathObject*' to non-scalar type 'MathObject' requested| ||=== Build     finished: 1 errors, 0 warnings (0 minutes, 0 seconds) ===|

I have been going over the code for a while now but I can not get it! If anyone can point out what is wrong I would love to hear.

Thanks!

Upvotes: 0

Views: 266

Answers (4)

T.C.
T.C.

Reputation: 137425

In C++ you can just make an object on the stack:

MathObject mo(3,4);

This statement creates a MathObject called mo on the stack, that will be automatically destroyed when main returns. This should be your preferred way of creating objects.

The new operator in C++, unlike the new operator in Java or C#, is not needed for creating an object and should generally be used very sparingly. It allocates memory from the heap for holding the object, which allows the object's lifetime to extend beyond the current function. But that also means that you are responsible for cleaning up with delete after you are done using the object, or the memory will be leaked.

MathObject *mo = new MathObject(3,4); // Never do this!

This is terrible code. It's a) inefficient (allocating from the heap with new is much more expensive than the stack) and b) unsafe, because if for some reason you fail to delete mo; (sometimes the reason is out of your control, such as an exception being thrown through your code) the memory is leaked.

std::unique_ptr<MathObject> mo(new MathObject(3,4));

This uses new to create a MathObject object on the heap, and stores the returned pointer in a unique_ptr object created on the stack. The unique_ptr object will automatically delete the pointer stored in it when the unique_ptr is destroyed. This is safe, but it's still much slower than the first version.

Upvotes: 4

Christophe
Christophe

Reputation: 73456

It's your object initalisation, here:

   MathObject mo = new MathObject(3,4);

You create a local object mo, then you you create another object somewhere on the heap and new returns a pointer to it. So your compiler understands that you want to assign a pointer to mo.

Replace your line with:

MathObject mo = MathObject(3,4);

or even:

MathObject mo(3,4);

Please note that these two forms give in fact the same result: in both case, the compiler generates only one object and one call to the constructor with the parameter(3,4), despite the "=" operator. To know more about this, look at: http://www.gotw.ca/gotw/001.htm .

Upvotes: 0

Moha the almighty camel
Moha the almighty camel

Reputation: 4473

the way you are creating a new object is how you would do it in C# or Java. in C++ it is better to avoid using new because you will have to keep memory management in mind and also it is much slower.

the little piece of code shows you how to use constructors:

#include <iostream>
using std::cout;
using std::endl;

class  MathObject{

    public:
    MathObject (){
        cout<<"Calling Default constructor"<<endl;
    }

    MathObject (int i, int j){
        x = i;
        y = j;
        cout<<"Calling constructors with two parameters"<<endl;
    }
    private:
    int x, y;
};


int main () {

    MathObject mo;
    MathObject mo2(3,4);

}

output:

Calling Default constructor
Calling constructors with two parameters

Upvotes: 0

Parth Kothari
Parth Kothari

Reputation: 23

Your declaration of MathObject is faulty. If you are dynamically allocating a MathObject, it should be

MathObject * mo = new MathObject(3,4);

And the sum function should be called using -> operator like this:

int sum = mo->sum();

Or if you want to create an object on the stack, you should not be using the new operator.

MathObject mo(3,4);
int sum = mo.sum();

That will do the trick.

Edit:

Here is how it works on the top level: The new operator searches for the free memory for your object (In your case that is a MathObject), and initializes a new object in the space using the constructor arguments you passed. Then, it returns a pointer to this newly created object. So on the lhs, you should be declaring a pointer that can point to a MathObject. That is why we have MathObject * mo and not Mathobject mo.

I hope that helps!

Upvotes: 0

Related Questions