Passing class byVal

 
	int text = ObjectCtrl->addObject(&newObject);


1
2
3
4
5
int ObjectController::addObject(Object* newObject)
{
	objectList.push_back(newObject);
	return objectList.size()-1;
}


As you can see, I am passing a pointer to a class through to this function.
The problem is, I actually want to pass the whole object, or copy it within the function. However, I don't know the data type of newObject. All I know is it is derived from the virtual class Object.

I thought of possibly implementing a getType() function into Object, but feel there must be an easier way.

My basic need it to add to objectList a pointer to newObject. But without newObject being destructed. >_<
Well, you have two choices here: 1) is to remove the asterisk and hope that Object has a defined copy constructor, and 2) is to leave the pointer and also take a pointer to a copy function
It looks like from the first line of code

 
int text = ObjectCtrl->addObject( &newObject );


that you are concerned about newObject going out of scope and being destroyed whereas your container still holds a pointer to it.

If so, then I think you have to dynamically allocate it.

1
2
Object* newObject = new ...();
int text = ObjectCtrl->addObject(newObject);


There are other more robust (IMHO) solutions but they all come down to dynamically allocating an instance somewhere.
Sorry, I didn't mention Object is an abstract class. Which is why I can't create a copy of it, or it at all.
I was going to settle for switch() all derived object types and creating them dynamically.
However, I think for this situation, I'll just change my entire approach. -_-
If it is an abstract class, make the addObject() function to accept any derived class/object by declaring it with abstract class type parameter. So that the caller method can pass any of its family member (derived) object to that function.

Within the fuction, like your switch, check it with dynamic_cast<> what exactly the passed-in argument/object type is.
It would look like:


ObjectController::addObject(MyAbstractType *newObject)
{
if (dynamic_cast<Derived1 *>(newObject)) // returns null, if it is not of Derived1 type
{
// ... some thing for Derived1
}
else if (dynamic_cast<Derived2 *><newObject))
{
//... some thing for Derived2
}
else
{
// ... some thing else
}
}

Check it out. Good luck :)
I think you want the clone pattern then.

1
2
3
4
5
6
7
8
9
class Object {
  virtual Object* clone() const = 0;
};

class Derived : public Object {
   // Derived must be CopyConstructible
   virtual Derived* clone() const
     { return new Derived( *this ); }
};


Now your addObject method can:

1
2
3
4
5
int ObjectController::addObject(Object* newObject)
{
	objectList.push_back( newObject->clone() );
	return objectList.size()-1;
}

Ah, what exactly does { return new Derived( *this ); } do?

I used an alternate way previously, however wish to implement this now.

I wish to have something of the following,
1
2
3
4
5
6
void ObjectController::getObject(IDirect3DDevice9* d3dDevice, Object* newObject)
{
	//The newObject passed is a 'Derived' pointer which I want to create a new alloc, eg
	//newObject = new <newObject type>(d3dDevice)
	
}

All objects have to constructor Object(IDirect3DDevice9* d3dDevice)
 
return new Derived( *this );


uses new to dynamically allocate a new instance of Derived.
*this is a reference to the object whose clone() method is called.
Therefore, if Derived is copy constructible, then new Derived( *this )
compiles and makes a copy of the object referenced by *this.

The idea is that the clone method, when called on an object, must make
a copy of itself.
Access violation reading location 0x00000000.
@ line,
ObjectCtrl->getObject(App->d3dDevice, background);
with,
1
2
3
4
void ObjectController::getObject(IDirect3DDevice9* d3dDevice, Object* newObject)
{
	newObject = newObject->clone();	
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Object
{
public:
	virtual void release()=0;
	virtual Object* clone() const=0;
};

class ObjectBackground : public Object
{
private:
	IDirect3DTexture9* background;	///< To store the background texture.
	//...
public:
	virtual ObjectBackground* clone() const
		{ return new ObjectBackground( *this ); }
	//... 


background hasn't been used prior to the getObject call.

Other than the obvious error, that all my objects have the constructor object(IDirect3DDevice9*)
I don't know why this isn't working.
If your derived class has pointers (looks like ObjectBackground does) then you probably need to write your own copy constructor, as the default one provided by the compiler won't deep copy pointers.

1
2
3
4
5
6
class ObjectBackground : public Object {
  public:
      ObjectBackground( const ObjectBackground& b ) :
         background( new IDirect3DTexture9( *b.background ) )
      { /* etc */ }
};


this will "deep copy" the background object also.
Topic archived. No new replies allowed.