c++ vectors
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!
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:
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]
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!
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!
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:
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:
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.
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!
)
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!
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;
}
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;
}
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;}
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
Popular Topics
Advertisement