By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,750 Members | 1,187 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,750 IT Pros & Developers. It's quick & easy.

public virtual and assignment operators

P: 2
Just ran into a problem upgrading from GCC 2.96 to GCC 3.3.2. There is a bug somewhere, could be in 2.96, could be in 3.3.2, could be in the code I'm compiling. Here's a minimal example

class A
{
public:
virtual int f() = 0;
private:
int a;
};

class B : public virtual A
{
};

class C: public virtual A
{
};

class D: public B, public C
{
public:
A* clone();
};

A*
D::clone()
{
return new D(*this);
}

The clone function uses the assignment operator (operator=) to return the new object.

The basis of this problem is that class A has data but no explicitly defined concrete functions.

The assignment operator in class D under both compilers correctly calls the assignment operators in classes B and C. Using GCC 2.96, assignment operators for both B and C call the assignment operator in A. While this does the work twice, at least it gets done.

Using 3.3.2, neither B nor C calls the assignment operator in A, so the new object contains uninitialized data.

Any idea which version of the compiler is correct (if either)? Should the assignment operator follow the same rules that constructors do, where the base class constructor is called first, and only once?

Thanks.
Sep 27 '06 #1
Share this Question
Share on Google+
2 Replies


P: 2
Just ran into a problem upgrading from GCC 2.96 to GCC 3.3.2. There is a bug somewhere, could be in 2.96, could be in 3.3.2, could be in the code I'm compiling. Here's a minimal example

class A
{
public:
virtual int f() = 0;
private:
int a;
};

class B : public virtual A
{
};

class C: public virtual A
{
};

class D: public B, public C
{
public:
A* clone();
};

A*
D::clone()
{
return new D(*this);
}

The clone function uses the assignment operator (operator=) to return the new object.

The basis of this problem is that class A has data but no explicitly defined concrete functions.

The assignment operator in class D under both compilers correctly calls the assignment operators in classes B and C. Using GCC 2.96, assignment operators for both B and C call the assignment operator in A. While this does the work twice, at least it gets done.

Using 3.3.2, neither B nor C calls the assignment operator in A, so the new object contains uninitialized data.

Any idea which version of the compiler is correct (if either)? Should the assignment operator follow the same rules that constructors do, where the base class constructor is called first, and only once?

Thanks.
I found a solution to this problem. I created an assignment operator for D, as follows:

D& D:: operator=(const D& d)
{
if (this == &d)
return;

A:: operator=(d);
B:: operator=(d);
C:: operator=(d)
return *this;
}

This emulates the order in which constructors are run when classes B and C user public virtual derivation.
Sep 27 '06 #2

100+
P: 144
Actually, the problem is that you shouldn't even be allowed to allocate on object of class D. Class A has a pure virtual function f() therefore making it an abstract class. Any classes that inherit this function, but don't define it remain abstract. I imagine older versions of gcc allowed you to shoot youself in the foot this way. I would expect that from 2.96, but not from 3.3.2. Here is the error you should get at compile time (using gcc 4.1.0):

Expand|Select|Wrap|Line Numbers
  1. virtual.cpp: In member function A* D::clone():
  2. virtual.cpp:26: error: cannot allocate an object of abstract type D
  3. virtual.cpp:18: note:   because the following virtual functions are pure within D:
  4. virtual.cpp:4: note:     virtual int A::f()
  5.  
Sep 27 '06 #3

Post your reply

Sign in to post your reply or Sign up for a free account.