tags:

views:

136

answers:

6

I'm trying to make a simple game engine. I've never used OOP before, so this is probably a simple mistake, but I get this error when trying to create an instance of a class.

invalid conversion from `World*' to `int'
initializing argument 1 of `World::World(int)'

This is the code to create the class.

  World w = new World(100);

And the actual class:

class World {
    int maxParts;
    public:
     GameObject **parts;
     World(int maxParts);
     int addObject(int type);
    private:
     int firstFreeId();
};

World::World(int maxParts)
{
    parts = new GameObject *[maxParts];
}

...

Thanks for any help.

+7  A: 

The new operator returns a pointer:

World *w = new World(100);

After having created a World object in this way, you would usually access it using the -> operator:

w->addObject(5);

When you're done with it, don't forget to delete it or you will have a memory leak:

delete w;
w = NULL;

Setting w = NULL is not strictly necessary, but it's good practice because it prevents you from accidentally accessing the object after it's been deleted.

Greg Hewgill
+5  A: 

You're missing an asterisk here:

World *w = new World(100);

When you create something with new it gives you a pointer to the new object, so the variable you put the pointer into must be declared with an asterisk.

RichieHindle
Thanks, that is exactly what I needed.
phpscriptcoder
A: 

I would highly recommend starting with C# or java instead of C++ to learn OOP.

Since this was received negatively I have edited the response. I was not trying to be obnoxious. My recommendation stands here is why:

First off I like Dave Hinton's reasons of course (thanks for chiming in), here are some more:

I think if you use .net or the Java sdk you'll have a lot more out of the box libraries and objects to tap into. I know plenty exist in C++ but are a little harder to acquire and piece together I think. I'm talking about much higher level objects than the STL of course. For instance in .net I can use something called a "MailMessage" to construct an email. I wouldn't know off hand how to do that these days with gcc and C++. I guess the emphasis here is on the framework support for Java or C# versus that of C++ (non .net C++ that is).

Next, I think namespaces are slightly easier in java and C# although I know this will probably get lash back.

Above all it boils down to the fact that if you look the proposed answers (and they're correct right?) you'll notice they would never have been an issue in Java or C#:

  1. destructor
  2. missing asterisk
  3. confusion (for beginners, at least was for me) between '.' and '->'
David
care to explain why?
markh44
Possible reasons include: not having to learn about manual memory management, not having to learn about pointers, not having to worry about the preprocessor. Although I would suggest learning OOP in PHP, a language the OP is already familiar with, which supports OOP these days.
Dave Hinton
That's much better, downvote removed. I agree those things you mention could be problematic for a beginner but I don't agree that those things would significantly hinder understanding OOP. Additionally, since the question mentioned games, perhaps the OP intends to get a job in games programming. Knowing C++ is essential for pretty much any games programming job I've ever seen.
markh44
+1 for the games point. True, he/she will have to learn C++ eventually :)
David
+12  A: 

new World(100) dynamically creates a new World object, passing 100 to the constructor, but evaluates to a pointer to the created object.

If you just want to construct a World object you don't need a new expression, you can just construct it directly:

World w(100);

The error you are getting is because you are trying to construct a World object based on the World pointer returned by the new expression. The only World constructor takes an int and you can't convert a pointer type to an int without an explicit cast.

Charles Bailey
This created the object, but when I tried to use a function of it I got an error that "w is not a class or object."Not sure what the problem is there... but I got one of the other solutions posted here to work.
phpscriptcoder
You need to post the full code that didn't work and the complete error message that it generated, then we have a chance to say what might be wrong with it.
Charles Bailey
+1  A: 

World w = foo; calls the constructor of World with the argument foo (unless foo is a World object already) and then calls the copy constructor of World with the result as an argument. new World(foo) calls the constructor of World with the argument foo, stores the result on the heap and returns a pointer to that.

So World w = new World(100) first creates a World object on the heap, calling the constructor with the arguemnt 100. It then calls the constructor again with the result of new World(100) as the argument (because World w = foo calls the constructor with foo as an argument) which does not work because the constructor does not accept arguments of type World*.

sepp2k
Your first statement is subtly incorrect. `World w = foo` calls the constructor of `World` with argument `foo`, thus creating a temporary; then, it calls copy constructor of `World` to instantiate `w` itself by copy from that temporary. Compiler is permitted to optimize away the copy step, but it must signal an error if there's no accessible copy constructor (even if it doesn't actually use it because of optimization). Note that VC++ is non-standard-conformant in that regard, and doesn't check for accessibility of elided constructors.
Pavel Minaev
"World w = foo calls the constructor of World with argument foo, thus creating a temporary; then, it calls copy constructor of World to instantiate w itself by copy from that temporary." No, it doesn't. `World w = foo` is the same as `World w(foo)`. So unless foo is actually a World object, there is no copy constructor being called. You're thinking of `World w = World(foo)`
sepp2k
@sepp2k: Pavel Minaev is right, `World w(foo)` is *direct initialization* and doesn't imply the use of a copy constructor. `World w = foo` is *copy initalization* and (logically) constructs a temporary `World` from `foo` and initalizes `w` from the temporary using the copy constructor. The two expressions have identical semantics only when `foo` is a `World` object. The compiler is allowed to elide the temporary in *copy initialization* but the copy constructor must still be accessible and the constructor used (nominally for the temporary) cannot be explicit. These are important differences.
Charles Bailey
So he is. I did not know that. Fixed now.
sepp2k
+3  A: 

You also need a destructor to clean up your pointer array.

World::~World()
{
    delete[] parts;
}

Note the different form of delete when deleting an array - this is critical.

Or you could use std::vector<GameObject*> and you won't have to worry about it.

markh44
+1 for mentioning `std::vector<>`.
Dave Hinton