Thread: deriving classes

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    630

    deriving classes

    Hello..

    I have class cone, ctwo and class out_2 in base class (cone) which is derived from out class.
    I want to have out_2 virtual, so I can define it in class ctwo..
    I want to be able to call function out_func() and someotherfunc() from ctwo class.

    Code:
    class out {
    public:
    	void out_func() { }
    };
    
    class cone {
    public:
    
    	virtual class out_2 : public out { }
    	out_2 cobject;
    };
    
    class ctwo : public cone {
    public:
    	class out_2 : public out {
    	public:
    		void someotherfunc() { }
    	};
    	
    	////////
    	void call() {
    		cobject.out_func();
    		cobject.someotherfunc();
    	}
    };
    
    int main() {
    	ctwo class_two;
    	class_two.call();
    	return 0;
    }
    I hope you can see from the code, what Im trying to do..
    Last edited by l2u; 01-14-2007 at 12:09 PM.

  2. #2
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    > want to have out_2 virtual, so I can define it in class ctwo..
    I have no idea what you mean by this. The definition of cone:ut_2 wouldn't affect ctwo:ut_2. And I'm fairly certain that using the virtual keyword to qualify a class isn't valid. (Not to mention you're missing all your trailing semicolons)
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  3. #3
    Registered User
    Join Date
    May 2006
    Posts
    630
    I want to make class virtual the way you make functions virtual (abstract classes). Is this even possible?

  4. #4
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    So you want ctwo instances to be able to access cobject from the base (cone) class? Maybe like this?
    Code:
    #include <iostream>
    
    class Base
    {
    public:
      Base(int data):data_(data){}
      void PrintData() { std::cout<<data_; }
    protected:
      int data_;
    };
    
    class Derived: public Base
    {
    public:
       Derived():Base(0){}
       void SetData(int data){ data_ = data; }
    };
    
    int main()
    {
      Derived d;
      d.SetData(5);
      d.PrintData();
    }
    As you can see, Derived can acess data_, and the virtual keyword isn't involed. May I suggest, though, that using protected data members if poor practice. It is better to provide an interface to base class data through base class protected functions (for example, providing a SetData method inside Base, and declaraing data_ as a private member).
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  5. #5
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    You can't make a nested class virtual as you do with member functions. A virtual member function is a function that the base class expects derived classes to redefine. You can't however redefine classes once they are defined. Well, not the same way. Read on...

    A nested class is not a normal member of your class. Remember it simply defines an object. It doesn't instantiate one. In other words it defines a new type inside the enclosing class scope. What is now left to know is the inheritance rules for nested classes. Take a look at the following example.

    Code:
    class Base {
    public:
        class Nested {
            public:
                int valNested;
        };
    
        int val Base;
    
    };
    
    class Derived: public Base {
    public:
    
        int valDerived;
    
    };
    The class Nested is defined inside Base, however, it is not instantiated as a member of this class. However, since it is defined inside the public access control label, it can be used by users of the Base class.

    The scope rules for nested classes state that a nested class scope is that of its enclosing class. That means Nested scope is Base. In C++ syntax, Base::Nested. So the bellow code is correct:
    Code:
    int main() {
    
        Base foo; // declares an instance of the class Base
    
        Base::Nested bar;  // declares an instance of the class Nested
    
    }
    So, what about the derived class? Derived classes are known to be composed of two parts; Their own non-static members and the non-static members of their base class. But the keyword here is members. It just so happens a nested class is not a normal member of a class. It simply defines a new type inside that class scope.

    However, I did say earlier the nested class is defined inside the scope of the base class. Can it be this definition is carried on through a derived class?
    Code:
    int main() {
    
       Derived foo;  // declares an instance of the derived class
    
       Derived::Nested bar;  // declares an instance of the class Nested
    
    }
    Yes, it can! So, all in all, you don't need to define again your nested class inside the derived class. The definition inside Base will carry over to its derived classes and follows the same rules concerning private, protected or public members.

    But lets try and do what you were trying to do and define Nested inside the derived class too:

    Code:
    class Derived: public Base {
    public:
        class Nested {
            public:
                int valNested;
        };
    
        int valDerived;
    
    };
    I changed Derived to look like the above. We now have the "same" class being defined twice. Once inside Base and another inside Derived. Notice I put same inside quotes... The thing is that they aren't the same. They are two different classes.

    Remember I said nested classes are defined inside the scope of the enclosing class. As such, the base class defines one nested class named Nested. While the derived class defines another nested class also named Nested. There isn't any compiler error because both Nesteds belong to different namespaces. And even being Derived a class that inherits from Base, there is still no conflict.

    Look:

    Code:
    int main()
    {
    
        Derived::Base::Nested foo;
        Derived::Nested bar;
    
    }
    On the first line I'm created an instance of Nested calling on the base portion of the Derived class (Base::Nested). On the second line I'm creating an instance Derived::Nested. Both Nested classes are different. They have the same name but they could have been defined completely different from each other.

    So, even if you thought you were redefining a class by repeating the definition inside the derived class, you weren't. You would be creating an entirely new class under the Derived scope, and effectively shadowing the definition of base (although still be able to access it, as demonstrated above).
    Last edited by Mario F.; 01-14-2007 at 07:51 PM.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  6. #6
    Registered User
    Join Date
    May 2006
    Posts
    630
    This is very helpful post, Mario F.

    The reason why I want to do this: (I will show with another example - I hope you will get it)
    For instance I have a class 'animals' that is a base class, and I have a member inside it:
    vector <animal_parts*> list; (animal_parts is another class).

    Default animal_parts as a base class
    Code:
    //class animal_parts with default members
    class animal_parts {
    public:
    	int m_height;
    	int m_width;
    };
    Now I want to make derived class dog with a base class animals:
    Code:
    class dog : public animals {
    }
    Now I want to define animal_parts (inside dog class) so it would fit for dog, for instance:
    Code:
    class dog_parts : public animal_parts {
    	int m_dog_width;
    	etc..
    }
    So now class 'animals' would be able to use data from base class animal_parts and store data in list, and I want dog class to be able to use dog_parts class (of course with animal_parts).

    Class would be actually stored in list: animal_parts *ptr = new dog_parts();

    With other words: class 'animals' only needs to know data in animal_parts (base class) because its used to process that data.. and derived class 'dog' is meant to process dog's data.

    I want to be able to do the same thing for another animal, which has different structure. Class animals would process the data that is the same for each animal, and derived class would do the rest of the work.

    I hope you can help me, any maybe recomment some different design for my problem if my approach is 'wrong'?

    I cant belive its so hard to explain.. I hope you got it..
    Last edited by l2u; 01-15-2007 at 06:57 AM.

  7. #7
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    You said so yourself, "class 'animals' only needs to know data in animal_parts (base class)".

    animal_parts is a base class, of which dog_parts, bird_parts, fish_parts are derived classes.

    Meanwhile, you have the base class animal, of which dog, bird, fish are derived classes.

    animal would contain animal_parts *ptr = new animal_parts()
    dog would contain animal_parts *ptr = new dog_parts()
    bird would contain animal_parts *ptr = new bird_parts()
    fish would contain animal_parts *ptr = new fish_parts()

    This is one way.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  8. #8
    Registered User
    Join Date
    May 2006
    Posts
    630
    At the moment, function in class 'animals' makes a new pointer to animal_parts, so it doesnt know anything about derived class.

    Maybe it would be good to make virtual function that would make the 'right' pointer and pass it to base class 'animals'.

    Or is there any better way?

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Have every derived class pass its newly created pointer down to the base class in the constructor.
    Code:
    derived() : base(new derived_parts) {}
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #10
    Registered User
    Join Date
    May 2006
    Posts
    630
    Quote Originally Posted by CornedBee
    Have every derived class pass its newly created pointer down to the base class in the constructor.
    Code:
    derived() : base(new derived_parts) {}
    Cool advice.

    What if I make the main base class (animals) templated?
    What would be better in your opinion?

  11. #11
    Registered User
    Join Date
    May 2006
    Posts
    630
    Quote Originally Posted by Mario F.
    dog would contain animal_parts *ptr = new dog_parts()
    bird would contain animal_parts *ptr = new bird_parts()
    fish would contain animal_parts *ptr = new fish_parts()
    How do I access derived class from ptr?

  12. #12
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> How do I access derived class from ptr?
    By calling functions that are declared as virtual in animal_parts and overridden in the derived classes. You rarely will want to directly access the derived class from ptr. If you do need to, then you might use a dynamic_cast.

  13. #13
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by l2u
    What if I make the main base class (animals) templated?
    What would be better in your opinion?
    Depends on your usage. I find your entire design strange in the first place.

    If you want to use animal polymorphically, then making the base a template would be wrong, as it would then no longer be a common base.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can you Initialize all classes once with New?
    By peacerosetx in forum C++ Programming
    Replies: 12
    Last Post: 07-02-2008, 10:47 AM
  2. Deriving from std::except
    By Mario F. in forum C++ Programming
    Replies: 5
    Last Post: 06-23-2007, 07:20 AM
  3. im extreamly new help
    By rigo305 in forum C++ Programming
    Replies: 27
    Last Post: 04-23-2004, 11:22 PM
  4. Exporting VC++ classes for use with VB
    By Helix in forum Windows Programming
    Replies: 2
    Last Post: 12-29-2003, 05:38 PM
  5. include question
    By Wanted420 in forum C++ Programming
    Replies: 8
    Last Post: 10-17-2003, 03:49 AM