|
-
February 1st, 2006, 05:40 AM
#1
Clone function (pure virtual base class)
Hello,
I'm trying to do the following:
Code:
class base
{
public:
base(data* p_base_data) {p_data = p_base_data};
virtual base* clone(data* p_clone_data = p_data) = 0;
protected:
data* p_data;
};
Every class inherited from base must now have it's own clone function. However there seems to be an error with the default parameter:
Code:
error: invalid use of non-static data member 'base::p_data'
Is a default parameter (using a protected data member) not allowed in this case. Or am I doing something wrong?
-
February 1st, 2006, 05:44 AM
#2
Re: Clone function (pure virtual base class)
Is a default parameter (using a protected data member) not allowed in this case. Or am I doing something wrong?
It is, but you're doing something wrong. You can't use non-static member p_data as default parameter.
-
February 1st, 2006, 05:46 AM
#3
Re: Clone function (pure virtual base class)
-
February 1st, 2006, 05:59 AM
#4
Re: Clone function (pure virtual base class)
I'm not sure, maybe you can do it like this instead?
Code:
class base
{
public:
base(data* p_base_data)
{
p_data = p_base_data;
}
base* clone()
{
return clone(p_data);
}
virtual base* clone(data* p_clone_data) = 0;
protected:
data* p_data;
};
- petter
-
February 1st, 2006, 06:26 AM
#5
Re: Clone function (pure virtual base class)
Thanks Cilu and Wildfrog,
However the problem is not solved:
Code:
class base
{
public:
base(data* p_base_data)
{
p_data = p_base_data;
}
base* clone()
{
return clone(p_data);
}
virtual base* clone(data* p_clone_data) = 0;
protected:
data* p_data;
};
class derived : public base
{
derived(data* p_derived_data) : base(p_derived_data)
{};
virtual base* clone(data* p_clone_data)
{
return new derived(p_clone_data);
}
}
I still cannot call clone() on a derived object with this solution, even if I make clone() virtual in the base class:
Code:
error: No matching function call to derived::clone()
Also I'm wondering why it is not allowed to use protected data members of the base class as default parameters of (pure) virtual functions defined in this base class.
Last edited by dus; February 1st, 2006 at 06:28 AM.
Reason: correction
-
February 1st, 2006, 06:26 AM
#6
Re: Clone function (pure virtual base class)
I don't know why you have defined clone that way but the solution is similar to wildfrog's only I would use do_clone as the virtual function thus:
Code:
class base
{
protected:
explicit base(data* p_base_data) : p_data( p_base_data )
{
}
public:
virtual ~base() {} // you must have a virtual destructor
base* clone()
{
return do_clone(p_data);
}
base* clone(data* p_clone_data)
{
return do_clone( p_clone_data );
}
protected:
data* p_data;
virtual base * do_clone( data * p_data ) = 0;
};
(And it's also likely that some of your functions should be const).
You can give your virtual destructor a body. (Maybe it calls some deleting method on p_data?) and disable copy-construction and assignment done the regular way (must call clone to copy).
-
February 1st, 2006, 10:21 AM
#7
Re: Clone function (pure virtual base class)
 Originally Posted by dus
I still cannot call clone() on a derived object with this solution, even if I make clone() virtual in the base class:
Code:
error: No matching function call to derived::clone()
You get this error because derived::clone( data* ) hides all overloaded versions of clone inherited from the base class. Because of C++'s name hiding rules, it's as if base::clone() was not inherited by the derived class! This surprised me too when I first learned about it just recently. It is explained well by Scott Meyers in Effective C++ (Third Edition) -- Item 33: "Avoid hiding inherited names."
The solution is to add a "using" statement in the derived class. Like so:
Code:
class derived : public base
{
derived(data* p_derived_data) : base(p_derived_data)
{};
using base::clone;
virtual base* clone(data* p_clone_data)
{
return new derived(p_clone_data);
}
}
That pulls in the other version of clone() that you did not override, and makes public inheritance work as expected.
-
February 1st, 2006, 10:25 AM
#8
Re: Clone function (pure virtual base class)
 Originally Posted by dus
Also I'm wondering why it is not allowed to use protected data members of the base class as default parameters of (pure) virtual functions defined in this base class.
You cannot dynamically bind default values in function definitions because the function type is defined statically and the default value is part of the function type. Thus the compiler must know the default value at compile time and does not figure it out at runtime.
NMTop40's approach (with the NVI idiom) was IMHO the best solution for this problem. But I still wonder whether whatever you want to do is well designed; sorry, but it looks a little strange to me.
-
February 1st, 2006, 01:12 PM
#9
Re: Clone function (pure virtual base class)
Actually, the whole thing doesn't make sense: why would a clone function need to take any arguments? the idea of clone is make a copy of a run-time object - all the information should be contained in the object that you're cloning.
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
February 2nd, 2006, 03:42 AM
#10
Re: Clone function (pure virtual base class)
The OP obviously does not want to create a typical clone function. I think he wants to create an object of a type that is defined dynamically by the type of another object. Thus he wants to 'clone' the type of an object with different data.
Maybe some kind of class factory e.g. like the MFC RuntimeClass would be appropriate here?!
-
February 2nd, 2006, 04:10 AM
#11
Re: Clone function (pure virtual base class)
 Originally Posted by Oliver M.
The OP obviously does not want to create a typical clone function. I think he wants to create an object of a type that is defined dynamically by the type of another object. Thus he wants to 'clone' the type of an object with different data.
Maybe some kind of class factory e.g. like the MFC RuntimeClass would be appropriate here?!
In which case, I'd strongly suggest thinking up a different name for the function, just to avoid confusion down the line.
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|