c++ vectors

Started by
11 comments, last by Instruo 19 years, 8 months ago
This has been happening to me a far bit in this project, and I've worked around it in the past but it's getting annoying. Has anyone else ever gotten this when trying to .push_back() a vector of class objects? error C2440: 'initializing' : cannot convert from 'const Piece' to 'Piece' Piece, of course, being the name of the class ; ) Anyway, thanks for any insight or input!
"Game Programming" in an of itself does not exist. We learn to program and then use that knowledge to make games.
Advertisement
Does Piece have an explicit copy constructor? If so, post it.
Yeah doesn't make sense unless you've written your copy constructor's arguments differently from what is expected. It should be of the form:

struct type {     type(const type& t);};


You don't have a write your own because a default is provided that does a member wise copy, you may need to write one if you have members that are pointers to define what means to copy properly.

[Edited by - snk_kid on August 20, 2004 5:51:34 AM]
I'm just using the default copy constructor. Piece itself doesn't have any pointers, but it does have a member which is a class object that has a couple of pointers. This project has been my first moderate attempt at using pointers, so I figured they were going to bite me a few times until I learn to treat them right ;)

Okay, so would I need to put in a specific copy constructor for the class that includes the pointers, instead of Piece?

Also, what would some examples be of different ways I could impliment the copy? (as in, I'm not exactly sure HOW it needs to copy, so some options might clear things up ;)

Thanks so much for your help!
"Game Programming" in an of itself does not exist. We learn to program and then use that knowledge to make games.
If you want to copy pointers, you need to do a memberwise copy as apposed to a shallow copy (the default).
A shallow copy simply copies the values, which in the case of a pointer, will copy where it points, not what it points to. This can create problems such as:

#include <iostream>class Cat{public:	Cat() {_age = new int;}	~Cat() {delete _age;}	int GetAge() const {return *_age;}	void SetAge(int value) {*_age = value;}private:	int * _age;};int main(){	Cat daisy;	daisy.SetAge(3);	std::cout << "Daisy is " << daisy.GetAge() << " year(s) old!\n";	Cat felix(daisy); //Create copy of daisy	felix.SetAge(4); //This will also change daisy's age!	std::cout << "Felix is " << felix.GetAge() << " year(s) old!\n";	std::cout << "Daisy is " << daisy.GetAge() << " year(s) old!\n";	return 0; //Now both cats will try to delete _age, causing major problems!} 


As you can see, a shallow copy simply doesn't work here.
The alternative is to create the copy constructor and assignment operators yourself and allocate the memory, so for the above example:

#include <iostream>class Cat{public:	Cat() {_age = new int;}	~Cat() {delete _age;}	Cat(const Cat &); //Copy constructor	Cat & operator=(const Cat &); //Assignment operator	int GetAge() const {return *_age;}	void SetAge(int value) {*_age = value;}private:	int * _age;};Cat::Cat(const Cat & rhs){	_age = new int;	*_age = *rhs._age;}Cat & Cat::operator=(const Cat & rhs){	*_age = *rhs._age;	return *this;}int main(){	Cat daisy;	daisy.SetAge(3);	std::cout << "Daisy is " << daisy.GetAge() << " year(s) old!\n";	Cat felix(daisy); //Create copy of daisy	felix.SetAge(4); //This is now fine	std::cout << "Felix is " << felix.GetAge() << " year(s) old!\n";	std::cout << "Daisy is " << daisy.GetAge() << " year(s) old!\n";	return 0; //Now both cats can safely delete their own _age!} 


If you create a copy constructor, the compiler will not create an assignment operator for you (and vice versa), so if you create one, you must create the other.

An alternative is to use smart pointers, but it depends on your needs.

Hope that cleared it up a bit.
that makes a bit more sense, thanks :) still running into issues, though. if I don't use 'const' in the copy constructor/assignment operator, it gives me the same message as above. (error C2440: 'initializing' : cannot convert from 'const Piece' to 'Piece'
)

When I do put const in, I get:

error C2662: 'Widget::ReturnParent' : cannot convert 'this' pointer from 'const Tetris_Box' to 'Widget &'


I know this is probably really ambiguous without the rest of the code, but if anyone has any 'pointers' (sorry, bad joke ;)), I'd really apprecaite it!
"Game Programming" in an of itself does not exist. We learn to program and then use that knowledge to make games.
I suppose I could at least put in the copy constructor/assignment functions ; )

Tetris_Box::Tetris_Box(Tetris_Box &original)
{
this->parent = new Widget;
*this->parent = *original.ReturnParent();
this->parent->AddChild(&*this);
this->h = original.GetT();
this->w = original.GetW();
this->t = original.GetT();
this->l = original.GetL();
this->z = original.GetZ();
this->background_image = original.GetBG();
}

Tetris_Box & Tetris_Box::operator= (Tetris_Box& original)
{
*this->parent = *original.ReturnParent();
this->parent->AddChild(&*this);
this->h = original.GetT();
this->w = original.GetW();
this->t = original.GetT();
this->l = original.GetL();
this->z = original.GetZ();
this->background_image = original.GetBG();

return *this;
}
"Game Programming" in an of itself does not exist. We learn to program and then use that knowledge to make games.
You'll probably want to guard against self-assignment in your operator=.
Tetris_Box & Tetris_Box::operator= (Tetris_Box& original){    // guard against self-assignment here    if( this == &original ) return *this;    *this->parent = *original.ReturnParent();    this->parent->AddChild(&*this);    this->h = original.GetT();    this->w = original.GetW();    this->t = original.GetT();    this->l = original.GetL();    this->z = original.GetZ();    this->background_image = original.GetBG();    return *this;}
We are the music makers and we are the dreamers of the dreams. - WonkaAsking Smart Questions | BookPool
Quote:Original post by Instruo
*this->parent = *original.ReturnParent();

Is ReturnParent a const function? if not, that's why you're getting errors when you declare original to be const.
Quote:Original post by Instruo
if I don't use 'const' in the copy constructor/assignment operator, it gives me the same message as above. (error C2440: 'initializing' : cannot convert from 'const Piece' to 'Piece'
)

When I do put const in, I get:

error C2662: 'Widget::ReturnParent' : cannot convert 'this' pointer from 'const Tetris_Box' to 'Widget &'

When you put const in the copy constructor and = operator, then all of the methods that you call on 'original' have to be declared as const. If you declare those methods to be const, then the 'this' pointer inside those functions will be const, and you can't assign it to a non-const pointer or pass it to a function that takes a non-const pointer. The const-ness needs to be consistent everwhere.

This topic is closed to new replies.

Advertisement