Sign in to follow this  

c++ vectors

This topic is 4861 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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!

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
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;
}

Share this post


Link to post
Share on other sites
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;
}


Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
okay, so I have my constructor/assignment guys going without consts, and they seem to be doing their job for their own sake, but I'm still getting the same

error C2440: 'initializing' : cannot convert from 'const Piece' to 'Piece'

:(

Share this post


Link to post
Share on other sites

This topic is 4861 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this