Thread: class vector member template

  1. #1
    Registered User
    Join Date
    Apr 2008
    Location
    Australia
    Posts
    55

    class vector member template

    Hi,

    Can't seem to get my head around templates enough to get something to work the way I want.

    Essentially I'm trying to create a class member variable that can store other class objects.

    Trying to achieve the following.
    pseudo code;

    Code:
    class UI : public OtherClass
    {
    public:
        //other stuff
        template <typename Wild>
        struct VARIABLE_OBJECT
        {
            Wild Obj;
            VARIABLE_OBJECT(Wild obj) {};
    
        };
        std::vector<VARIABLE_OBJECT> m_Variable;
    };
    
    class Object1
    {
        //functions, variables etc
    };
    
    class Object2
    {
        //functions, variables etc
    };
    
    
    main()
    {
    
        // here where m_Variable = VARIABLE_OBJECT either object1 or object2 type etc
    
        m_Variable.push_back(Object1);
        std::vector<VARIABLE_OBJECT>::iterator itObj;
        itObj = m_Variable.begin();
    
       for(itObj = m_Variable.begin() ;itObj !m_Variable.end();itObj++)
         itObj->items;
    
    };
    Where m_Variable is able to be different objects at runtime.

    Maybe I'm going about it the wrong way, so open to suggestions but I'd like to do without inheritance for this with UI class.

    Any pointers would be great thanks

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Tropod
    Where m_Variable is able to be different objects at runtime.

    Maybe I'm going about it the wrong way, so open to suggestions but I'd like to do without inheritance for this with UI class.
    Since you want the choice to happen at runtime, it sounds like inheritance and polymorphism will be appropriate.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Apr 2008
    Location
    Australia
    Posts
    55
    Thanks for the reply.

    How would one iterate through objects, given the following;

    Code:
    class UI : public OtherClass
    {
    public:
        //other stuff
        template <typename Wild>
        struct VARIABLE_OBJECT
        {
            Wild Obj;
            VARIABLE_OBJECT(Wild obj) {};
     
        };
        std::vector<VARIABLE_OBJECT> baseclass;
    };
    
    
    main()
    {
     
       baseclass.push_back(derivedClass);
    
       std::vector<BASE_CLASS>::iterator itDerivedClass;
     
       for(itDerivedClass = baseclass.begin() ;itDerivedClass !baseclass.end();itDerivedClass++)
         itDerivedClass->items;
     
    };

    It's my understanding that iterating through objects, thus their functions, will be done based on base class & not the derived class? Is there a way around this?
    If I use inheritance/polymorphism it solves the problem up until I need to iterate through the objects. That's why thought maybe templates would help, as the type that is being push_back isn't known until runtime, but need a generic global/member variable for this .

    I could go about it a different way with a whole bunch of if()'s, but it's something I'd like to learn to do this way somehow if possible .

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    It's my understanding that iterating through objects, thus their functions, will be done based on base class & not the derived class?
    Iterating will be done through a base class pointer at some point in the code, but if you actually used polymorphism, the derived objects will end up invoking their own functions.

  5. #5
    Registered User
    Join Date
    Apr 2008
    Location
    Australia
    Posts
    55
    Alrighty back to the drawing board then, I'm obviously missing something.
    Thanks for the reply .

  6. #6
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Alrighty back to the drawing board then, I'm obviously missing something.
    That would be: templates are resolved at compile-time. You are trying to do things with them at run-time.

    Just to be clear, you can use the instantiations of templates at run-time; that's not what you are trying to do.

    Code:
    int sSize;
    std::cin >> sSize;
    std::array<int, s> sData; // This will never work regardless of decorations.
    // The value of the variable `sSize' is unknown at compile-time so the compiler can not
    // build a class based on the `std::array<???, ???>' template.

    Code:
    int sSize;
    std::cin >> sSize;
    std::vector<int> sData(sSize); // This works.
    // The compiler knows everything it needs to know to build the class based on the `std::vector<???>' template.
    // The variable `sData' is an instance of the class that the compiler builds.
    Soma

  7. #7
    Registered User
    Join Date
    Apr 2008
    Location
    Australia
    Posts
    55
    Thanks for the replies

    What am I missing here?
    Works with pointer, but not iterator?

    Code:
    class BASE
    {
    public:
    	BASE() {  };
    	~BASE() { };
    	virtual void Message() { cout << "Base"; };
    };
    
    class DERIVED: public BASE
    {
    public:
    	DERIVED() ;
    	DERIVED(int A,int B);
    	~DERIVED() {} ;
    	void Message() { cout << "DERIVED"; } ;
    };
    
    
    std::vector<BASE> Base; //declared as variable in header.
    
    
    int main()
    {
    	DERIVED objDerived;
    	Base.push_back( objDerived );
    	std::vector<BASE>::iterator itBase;
    
    	for( itBase = Base.begin() ; itBase!= Base.end(); itBase ++)
    		itBase->Message(); //returns base Message(), not derived?
    
    	pBase = &objDerived;
    	for(int i=0; i<1;i++)
    		pBase->Message(); //returns derived Message().
    }

    How does one use an iterator here to run through derived objects function calls?
    Last edited by Tropod; 06-01-2012 at 06:54 AM. Reason: typo

  8. #8
    Registered User antred's Avatar
    Join Date
    Apr 2012
    Location
    Germany
    Posts
    257
    Quote Originally Posted by Tropod View Post
    Thanks for the replies

    What am I missing here?
    Works with pointer, but not iterator?

    Code:
    class BASE
    {
    public:
        BASE() {  };
        ~BASE() { };
        virtual void Message() { cout << "Base"; };
    };
    
    class DERIVED: public BASE
    {
    public:
        DERIVED() ;
        DERIVED(int A,int B);
        ~DERIVED() {} ;
        void Message() { cout << "DERIVED"; } ;
    };
    
    
    std::vector<BASE> Base; //declared as variable in header.
    
    
    int main()
    {
        DERIVED objDerived;
        Base.push_back( objDerived );
        std::vector<BASE>::iterator itBase;
    
        for( itBase = Base.begin() ; itBase!= Base.end(); itBase ++)
            itBase->Message(); //returns base Message(), not derived?
    
        pBase = &objDerived;
        for(int i=0; i<1;i++)
            pBase->Message(); //returns derived Message().
    }

    How does one use an iterator here to run through derived objects function calls?

    You've just become the victim of "slicing" (look it up on Wikipedia). The short answer is that you need to store your instances not by value but by pointer, i.e. your std::vector<BASE> Base; needs to become std::vector<BASE*> Base;. Oh, what the heck, I'll just go ahead and modify your program to show you what I mean.

    Code:
    class BASE
    {
    public:
        BASE() {  };
        ~BASE() { };
        virtual void Message() { cout << "Base"; };
    };
    
    class DERIVED: public BASE
    {
    public:
        DERIVED() ;
        DERIVED(int A,int B);
        ~DERIVED() {} ;
        void Message() { cout << "DERIVED"; } ;
    };
    
    
    std::vector<BASE*> Base; //declared as variable in header.
    
    
    int main()
    {
        DERIVED objDerived;
        Base.push_back( &objDerived );
        std::vector<BASE*>::iterator itBase;
    
        for( itBase = Base.begin() ; itBase!= Base.end(); itBase ++)
            ( *itBase )->Message(); // should print "DERIVED" now
    
        pBase = &objDerived;
        for(int i=0; i<1;i++)
            pBase->Message(); //returns derived Message().
    }
    Oh, by the way, it is more efficient to use preincrement on iterators, i.e. not itBase++ but ++itBase.

  9. #9
    Registered User antred's Avatar
    Join Date
    Apr 2012
    Location
    Germany
    Posts
    257
    And another thing, if you ever delete an instance of a class derived from BASE through a BASE* pointer, your ~BASE() destructor absolutely needs to be virtual. Otherwise, the correct destructor might not be called.

  10. #10
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by antred View Post
    And another thing, if you ever delete an instance of a class derived from BASE through a BASE* pointer, your ~BASE() destructor absolutely needs to be virtual. Otherwise, the correct destructor might not be called.
    The result of that "otherwise" is undefined behaviour, which is not necessarily the same thing as calling the wrong destructor.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  11. #11
    Registered User antred's Avatar
    Join Date
    Apr 2012
    Location
    Germany
    Posts
    257
    That is true, but I did say "might".

  12. #12
    Registered User
    Join Date
    Apr 2008
    Location
    Australia
    Posts
    55
    Thank you everyone for response! Very helpful
    So now have the following pseudo code;

    Code:
    class BASE
    {
    public:
        BASE() {  };
        ~BASE() { };
        virtual void Message() { cout << "Base"; };
    };
     
    class DERIVED: public BASE
    {
    public:
        DERIVED() ;
        DERIVED(int A,int B);
        ~DERIVED() {} ;
        void Message() { cout << "DERIVED"; } ;
    };
     
     
    std::vector<BASE*> Base; //declared as variable in header.
    
    
    Foo::Foo(std::vector<BASE*> &vBase)
    {
    
       BASE *pBase;
       DERIVED *pDerived;
       DERIVED_LEFT *pLeft;   
       DERIVED_RIGHT *pRight;   
    
       for(int i=0;i<filesize;i++)
       {
         switch(derived_type)
         {
         case derived_basic:
         pDerived = new DERIVED;
         pBase = pDerived;
         pDerived->member = 123;
         break;
    
         case derived_left:
         pLeft = new DERIVED_LEFT;
         pBase = pLeft;
         pLeft->member = 222;
         break;
       
         case derived_right:
         pRight = new DERIVED_RIGHT;
         pBase = pRight;
         pRight->member = 333;
         break;
    
         vBase.push_back(pBase);
       }
    }
     
     
    int main()
    {
        Foo(Base);
    
        std::vector<BASE*>::iterator itBase;
        for( itBase = Base.begin() ; itBase!= Base.end(); ++itBase)
            ( *itBase )->Message(); // returns DERIVED class
    }

    What's the proper way to delete these new allocated given this?
    ?
    Code:
        std::vector<BASE*>::iterator itBase;
        for( itBase = Base.begin() ; itBase!= Base.end(); ++itBase)
            delete[] ( *itBase );

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Static member initialization with class template
    By threahdead in forum C++ Programming
    Replies: 6
    Last Post: 04-28-2011, 12:16 AM
  2. Replies: 3
    Last Post: 01-30-2011, 04:28 PM
  3. how to define a static member in a template class
    By wanziforever in forum C++ Programming
    Replies: 3
    Last Post: 10-08-2009, 04:44 AM
  4. Replies: 5
    Last Post: 03-01-2008, 02:05 PM
  5. using push back function of a vector class template
    By anti-hw in forum C++ Programming
    Replies: 1
    Last Post: 07-20-2002, 11:25 AM

Tags for this Thread