CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Jul 2005
    Posts
    22

    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?

  2. #2
    Join Date
    Oct 2002
    Location
    Timisoara, Romania
    Posts
    14,360

    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.
    Marius Bancila
    Home Page
    My CodeGuru articles

    I do not offer technical support via PM or e-mail. Please use vbBulletin codes.

  3. #3
    Join Date
    Jul 2005
    Posts
    22

    Re: Clone function (pure virtual base class)

    Why not?

  4. #4
    Join Date
    Apr 2005
    Location
    Norway
    Posts
    3,934

    Re: Clone function (pure virtual base class)

    Why not?
    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

  5. #5
    Join Date
    Jul 2005
    Posts
    22

    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

  6. #6
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    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).

  7. #7
    Join Date
    May 2005
    Posts
    151

    Re: Clone function (pure virtual base class)

    Quote 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.

  8. #8
    Join Date
    May 2004
    Posts
    75

    Re: Clone function (pure virtual base class)

    Quote 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.

  9. #9
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    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


  10. #10
    Join Date
    May 2004
    Posts
    75

    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?!

  11. #11
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: Clone function (pure virtual base class)

    Quote 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
  •  





Click Here to Expand Forum to Full Width

Featured