Problems accessing methods of derived class

Discussion in 'C++' started by Jessica, Aug 31, 2006.

  1. Jessica

    Jessica Guest

    I have a base class and a derived class, but I am getting errors when I
    try to access functions of the derived class.

    Simplified version of my code is as follows:

    ////////////////
    // test2.hh

    class BaseClass {

    public:
    BaseClass();
    ~BaseClass();

    };

    class DerivedClass : public BaseClass {

    public:
    DerivedClass() {}
    ~DerivedClass() {}

    void setup();

    };

    ////////////////
    // test2.cc

    #include "test2.hh"

    int main() {

    BaseClass* object;

    object = new DerivedClass();
    object->setup();

    return 0;
    }


    When I try to compile this, I get the error:
    test2.cc:8: error: `setup' undeclared (first use this function)


    If I change the line to say:
    object->DerivedClass::setup();

    I get the error:
    test2.cc:8: error: type `DerivedClass' is not a base type for type
    `BaseClass'


    And if I change the pointer declaration to say:
    DerivedClass* object;

    I get the linker error:
    /tmp/ccaPvY8l.o: In function `main':
    test2.cc:(.text+0x68): undefined reference to `DerivedClass::setup()'
    /tmp/ccaPvY8l.o: In function `DerivedClass::DerivedClass[in-charge]()':
    test2.cc:(.gnu.linkonce.t._ZN12DerivedClassC1Ev+0xd): undefined
    reference to `BaseClass::BaseClass[not-in-charge]()'
    collect2: ld returned 1 exit status


    Can I change the declaration of DerivedClass so that I can use it as in
    the code given? Or am I going about this the wrong way completely?
    Jessica, Aug 31, 2006
    #1
    1. Advertising

  2. Jessica

    Shooting Guest

    Jessica wrote:
    > I have a base class and a derived class, but I am getting errors when I
    > try to access functions of the derived class.
    >
    > Simplified version of my code is as follows:
    >
    > ////////////////
    > // test2.hh
    >
    > class BaseClass {
    >
    > public:
    > BaseClass();
    > ~BaseClass();
    >
    > };
    >
    > class DerivedClass : public BaseClass {
    >
    > public:
    > DerivedClass() {}
    > ~DerivedClass() {}
    >
    > void setup();
    >
    > };
    >
    > ////////////////
    > // test2.cc
    >
    > #include "test2.hh"
    >
    > int main() {
    >
    > BaseClass* object;
    >
    > object = new DerivedClass();
    > object->setup();
    >
    > return 0;
    > }
    >
    >
    > When I try to compile this, I get the error:
    > test2.cc:8: error: `setup' undeclared (first use this function)
    >

    You don't declare it in base class, of course you cann't use it
    >
    > If I change the line to say:
    > object->DerivedClass::setup();
    >
    > I get the error:
    > test2.cc:8: error: type `DerivedClass' is not a base type for type
    > `BaseClass'
    >

    This syntax is for you to call the function defined in base.
    >
    > And if I change the pointer declaration to say:
    > DerivedClass* object;
    >
    > I get the linker error:
    > /tmp/ccaPvY8l.o: In function `main':
    > test2.cc:(.text+0x68): undefined reference to `DerivedClass::setup()'
    > /tmp/ccaPvY8l.o: In function `DerivedClass::DerivedClass[in-charge]()':
    > test2.cc:(.gnu.linkonce.t._ZN12DerivedClassC1Ev+0xd): undefined
    > reference to `BaseClass::BaseClass[not-in-charge]()'
    > collect2: ld returned 1 exit status
    >

    This is because you only defined the function but not define it
    >
    > Can I change the declaration of DerivedClass so that I can use it as in
    > the code given? Or am I going about this the wrong way completely?


    Yeah, you have to study more carefully on c++

    Just declare a setup() in Base class as a virtual function, you'll get
    what you want
    Shooting, Aug 31, 2006
    #2
    1. Advertising

  3. Jessica

    Salt_Peter Guest

    Jessica wrote:
    > I have a base class and a derived class, but I am getting errors when I
    > try to access functions of the derived class.
    >
    > Simplified version of my code is as follows:
    >

    < clipped>
    >
    > int main() {
    >
    > BaseClass* object;
    >
    > object = new DerivedClass();
    > object->setup();
    >
    > return 0;
    > }


    OK, you are going to learn something today.

    If you plan to use a pointer to a base class, you are attempting to
    implement a polymorphic solution. That means that you have to equip
    your classes with a vtable. The way this is done is simply by declaring
    at least one function as virtual. In this case, a virtual destructor
    will suffice. That means that you constructing a C++ program, not C.

    Also, if the plan is to reuse these various classes, declare them in
    their own headers with include guards. So you'll need 2 header files, 2
    corresponding implementation files (which i'm skipping here) + an
    implementation file for main(). My guess is that you are looking to
    make setup() virtual as well.

    Note that #ifndef, #define and #endif are used to supply header guards
    in order to prevent your linker from including the same header file
    multiple times. For all intensive purposes, you can ignore include
    guards when you are reading these classes. Include guards are only for
    the linker.

    ////////////////
    // baseclass.h

    #ifndef BASECLASS_H_
    #define BASECLASS_H_

    class BaseClass
    {

    public:
    BaseClass() { }
    virtual ~BaseClass() { }
    virtual void setup() { }
    };

    #endif /* BASECLASS_H_ */

    ////////////////
    // derivedclass.h

    #ifndef DERIVEDCLASS_H_
    #define DERIVEDCLASS_H_

    #include "baseclass.h"

    class DerivedClass : public BaseClass
    {
    public:
    DerivedClass() { }
    ~DerivedClass() { } // virtual
    void setup() { } // virtual
    };

    #endif /* DERIVEDCLASS_H_ */

    ////////////////
    // proj_test.cpp

    #include "derivedclass.h"

    int main()
    {
    BaseClass* object;
    object = new DerivedClass;
    object->setup();
    delete object;

    return 0;
    }

    Note that DerivedClass's destructor and DerivedClass's setup() are
    virtual because of inheritance.


    >
    > When I try to compile this, I get the error:
    > test2.cc:8: error: `setup' undeclared (first use this function)


    Thats because you never provided setup's implementation.
    void setup(); // is a declaration with no implementation (yet)
    void setup() { } // is a declaration with implementation which doesn't
    do anything right now

    >
    >
    > If I change the line to say:
    > object->DerivedClass::setup();
    >
    > I get the error:
    > test2.cc:8: error: type `DerivedClass' is not a base type for type
    > `BaseClass'


    Their isn't any vtable available and DerivedClass is not a base class.

    >
    >
    > And if I change the pointer declaration to say:
    > DerivedClass* object;
    >
    > I get the linker error:
    > /tmp/ccaPvY8l.o: In function `main':
    > test2.cc:(.text+0x68): undefined reference to `DerivedClass::setup()'
    > /tmp/ccaPvY8l.o: In function `DerivedClass::DerivedClass[in-charge]()':
    > test2.cc:(.gnu.linkonce.t._ZN12DerivedClassC1Ev+0xd): undefined
    > reference to `BaseClass::BaseClass[not-in-charge]()'
    > collect2: ld returned 1 exit status


    The compiler is basicly telling you that their is no base class
    available with an implementation of setup() available to compile with.

    Note that you can seperate your declaration and implementation like
    so...

    ////////////////
    // derivedclass.h

    #ifndef DERIVEDCLASS_H_
    #define DERIVEDCLASS_H_

    #include "baseclass.h"

    class DerivedClass : public BaseClass
    {
    public:
    DerivedClass();
    ~DerivedClass();
    void setup();
    };

    #endif /* DERIVEDCLASS_H_ */

    ////////////////
    // derivedclass.cpp

    #include "derivedclass.h"

    DerivedClass::DerivedClass()
    {
    }

    DerivedClass::~DerivedClass()
    {
    }

    void DerivedClass::setup()
    {
    }

    /* end of derivedclass.cpp */

    >
    >
    > Can I change the declaration of DerivedClass so that I can use it as in
    > the code given? Or am I going about this the wrong way completely?


    To implement a polymorphic solution, you need to compile a C++ program
    with the base class equipped with a vtable (at least one virtual
    function - a virtual destructor wiil do)

    Just for the sake of clarity, try compiling the following and carefully
    note which function gets called and what destructors get invoked. Then
    try compiling the same program without the virtual keywords (virtual is
    the key). Remember: virtual is what makes the vtable.

    // proj_test.cpp
    //

    #include <iostream>
    #include <ostream>

    class Base
    {
    public:
    Base() { std::cout << "Base()\n"; }
    virtual ~Base() { std::cout << "~Base()\n"; }
    virtual void setup() { std::cout << "Base::setup()\n"; }
    };

    class Derived : public Base
    {
    public:
    Derived() { std::cout << "Derived()\n"; }
    ~Derived() { std::cout << "~Derived()\n"; }
    void setup() { std::cout << "Derived::setup()\n"; }
    };

    int main()
    {
    std::cout << "___ Base pointer, Derived object ___\n";
    Base* object;
    object = new Derived;
    object->setup();
    delete object;

    std::cout << "\n___ Base pointer, Base object ___\n";
    Base* base;
    base = new Base;
    base->setup();
    delete base;

    return 0;
    }

    /*

    ___ Base pointer, Derived object ___
    Base()
    Derived()
    Derived::setup()
    ~Derived()
    ~Base()

    ___ Base pointer, Base object ___
    Base()
    Base::setup()
    ~Base()

    */
    Salt_Peter, Aug 31, 2006
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Taran
    Replies:
    6
    Views:
    381
    Default User
    Apr 20, 2006
  2. Replies:
    1
    Views:
    394
    myork
    May 23, 2007
  3. Replies:
    1
    Views:
    386
    Victor Bazarov
    May 23, 2007
  4. ma740988
    Replies:
    1
    Views:
    348
    Michael DOUBEZ
    Sep 18, 2008
  5. Kenneth McDonald
    Replies:
    5
    Views:
    314
    Kenneth McDonald
    Sep 26, 2008
Loading...

Share This Page