C2244 and inheritance error
-
I have a simple base class that holds id's for use in sorting other classes. It is a non-templated class in an single hpp file ( indexedObject, see below ) class indexedObject { public: indexedObject() : _mID(BAD_DB_ID) {} indexedObject(dbID id) : _mID(id) {} ~indexedObject(); dbID getID(void); void setID(dbID id); bool operator<(const dbID& param) const; bool operator>(const dbID& param) const; bool operator==(const dbID& param) const; bool operator!=(const dbID& param) const; protected: dbID _mID; }; // indexedObject inline indexedObject::~indexedObject() { _mID = BAD_DB_ID; } inline dbID indexedObject::getID(void) { return _mID; } inline void indexedObject::setID(dbID id) { _mID = id; } inline bool indexedObject::operator<(const dbID& param) const { return (_mID < param); } inline bool indexedObject::operator>(const dbID& param) const { return (_mID > param); } inline bool indexedObject::operator==(const dbID& param) const { return (_mID == param); } inline bool indexedObject::operator!=(const dbID& param) const { return (_mID != param); } I have a templated class that inherits from the base class. template class fwdCurve : public indexedObject, public broadCaster { blah blah... } When I try to define setID in the derived class template void fwdCurve<_Ty>::setID(dbID id) I get a C2244: indexedObject::setID : unable to match function definition to an existing declaration I am able to work around this by declaring setID() in the derived class definition and explicitly calling the base class method but why is this happening? I have VS 2005 with SP1 and hotfix KB930859 installed.
-
I have a simple base class that holds id's for use in sorting other classes. It is a non-templated class in an single hpp file ( indexedObject, see below ) class indexedObject { public: indexedObject() : _mID(BAD_DB_ID) {} indexedObject(dbID id) : _mID(id) {} ~indexedObject(); dbID getID(void); void setID(dbID id); bool operator<(const dbID& param) const; bool operator>(const dbID& param) const; bool operator==(const dbID& param) const; bool operator!=(const dbID& param) const; protected: dbID _mID; }; // indexedObject inline indexedObject::~indexedObject() { _mID = BAD_DB_ID; } inline dbID indexedObject::getID(void) { return _mID; } inline void indexedObject::setID(dbID id) { _mID = id; } inline bool indexedObject::operator<(const dbID& param) const { return (_mID < param); } inline bool indexedObject::operator>(const dbID& param) const { return (_mID > param); } inline bool indexedObject::operator==(const dbID& param) const { return (_mID == param); } inline bool indexedObject::operator!=(const dbID& param) const { return (_mID != param); } I have a templated class that inherits from the base class. template class fwdCurve : public indexedObject, public broadCaster { blah blah... } When I try to define setID in the derived class template void fwdCurve<_Ty>::setID(dbID id) I get a C2244: indexedObject::setID : unable to match function definition to an existing declaration I am able to work around this by declaring setID() in the derived class definition and explicitly calling the base class method but why is this happening? I have VS 2005 with SP1 and hotfix KB930859 installed.
mjackson11 wrote:
When I try to define setID in the derived class template void fwdCurve<_Ty>::setID(dbID id) I get a C2244: indexedObject::setID : unable to match function definition to an existing declaration
Yes - this is the way C++ works...you need a method declaration in the class before you can define it. The declaration in the base class does not change this.
mjackson11 wrote:
I am able to work around this by declaring setID() in the derived class definition and explicitly calling the base class method but why is this happening?
If you just want to call the base classes implementation, then you need no method definition or declaration in the derived class. What are you actually trying to accomplish?
-
mjackson11 wrote:
When I try to define setID in the derived class template void fwdCurve<_Ty>::setID(dbID id) I get a C2244: indexedObject::setID : unable to match function definition to an existing declaration
Yes - this is the way C++ works...you need a method declaration in the class before you can define it. The declaration in the base class does not change this.
mjackson11 wrote:
I am able to work around this by declaring setID() in the derived class definition and explicitly calling the base class method but why is this happening?
If you just want to call the base classes implementation, then you need no method definition or declaration in the derived class. What are you actually trying to accomplish?
Sorry, to be more specific, I tried to implement setID() in the derived class without putting setID in the class declaration. That's when it threw the error. If I define setID in the derived class declaration, when I implement it, it does not call the base class setID method. Seems like the compiler is defining them as two different methods instead of the derived class inhereting.
-
Sorry, to be more specific, I tried to implement setID() in the derived class without putting setID in the class declaration. That's when it threw the error. If I define setID in the derived class declaration, when I implement it, it does not call the base class setID method. Seems like the compiler is defining them as two different methods instead of the derived class inhereting.
mjackson11 wrote:
If I define setID in the derived class declaration, when I implement it, it does not call the base class setID method. Seems like the compiler is defining them as two different methods instead of the derived class inhereting.
Yep, that's the way most (if not all) OO languages work. The point is that if you do want to call the base classes method, you can very easily. However, if the language automatically called the base classes methods and you didn't want that to happen, you're stuffed. Anyway - in conclusion, what you've described is the way C++ is meant to work.
-
Sorry, to be more specific, I tried to implement setID() in the derived class without putting setID in the class declaration. That's when it threw the error. If I define setID in the derived class declaration, when I implement it, it does not call the base class setID method. Seems like the compiler is defining them as two different methods instead of the derived class inhereting.
I wasn't entirely clear about the one case when base class methods are called automatically. If a base class implements a method and your derived class doesn't declare or define it, then the base class method is automatically called. Consider this code:
#include <iostream> class Base { public: void A() { std::cout << "Base::A\n"; } void B() { std::cout << "Base::A\n"; } virtual void C() { std::cout << "Base::C\n"; } }; class Derived : public Base { public: void A() { std::cout << "Derived::A\n"; } virtual void C() { std::cout << "Derived::C\n"; } }; void VirtualTest(Base* pBase, const char* objName) { std::cout << "Calling pBase->A() with pBase = " << objName << "...\n"; pBase->A(); std::cout << "Calling pBase->C() with pBase = " << objName << "...\n"; pBase->C(); } int main(int, char**) { Base base; Derived derived; std::cout << "Calling base.A()...\n"; base.A(); std::cout << "Calling base.B()...\n"; base.B(); VirtualTest(&base, "&base"); std::cout << "Calling derived.A()...\n"; derived.A(); std::cout << "Calling derived.B()...\n"; derived.B(); VirtualTest(&derived, "&derived"); }
You should get this output:Calling base.A()...
Base::A
Calling base.B()...
Base::A
Calling pBase->A() with pBase = &base...
Base::A
Calling pBase->C() with pBase = &base...
Base::C
Calling derived.A()...
Derived::A
Calling derived.B()...
Base::A
Calling pBase->A() with pBase = &derived...
Base::A
Calling pBase->C() with pBase = &derived...
Derived::CSo -
Derived
overrides theA()
andC()
fromBase
and inheritsB()
fromBase
. The difference between overriding virtual and non-virtual methods is demonstrated inVirtualTest
- when you have a pointer tobase
,Base::A()
gets called becauseA()
is non-virtual, whereas the implementation ofC()
that is called depends on the actual type of the object that is pointed to, not the type of the pointer. -
Sorry, to be more specific, I tried to implement setID() in the derived class without putting setID in the class declaration. That's when it threw the error. If I define setID in the derived class declaration, when I implement it, it does not call the base class setID method. Seems like the compiler is defining them as two different methods instead of the derived class inhereting.
In addition to Stuart's replies... You haven't used "virtual' anywhere, so a method implementation in a derived class has nothing to do with a base class' method. Even if you use "virtual", you'd still need to include botht the definition and the implementation in the derived class, and call the base class method explicitly if desired. Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
I wasn't entirely clear about the one case when base class methods are called automatically. If a base class implements a method and your derived class doesn't declare or define it, then the base class method is automatically called. Consider this code:
#include <iostream> class Base { public: void A() { std::cout << "Base::A\n"; } void B() { std::cout << "Base::A\n"; } virtual void C() { std::cout << "Base::C\n"; } }; class Derived : public Base { public: void A() { std::cout << "Derived::A\n"; } virtual void C() { std::cout << "Derived::C\n"; } }; void VirtualTest(Base* pBase, const char* objName) { std::cout << "Calling pBase->A() with pBase = " << objName << "...\n"; pBase->A(); std::cout << "Calling pBase->C() with pBase = " << objName << "...\n"; pBase->C(); } int main(int, char**) { Base base; Derived derived; std::cout << "Calling base.A()...\n"; base.A(); std::cout << "Calling base.B()...\n"; base.B(); VirtualTest(&base, "&base"); std::cout << "Calling derived.A()...\n"; derived.A(); std::cout << "Calling derived.B()...\n"; derived.B(); VirtualTest(&derived, "&derived"); }
You should get this output:Calling base.A()...
Base::A
Calling base.B()...
Base::A
Calling pBase->A() with pBase = &base...
Base::A
Calling pBase->C() with pBase = &base...
Base::C
Calling derived.A()...
Derived::A
Calling derived.B()...
Base::A
Calling pBase->A() with pBase = &derived...
Base::A
Calling pBase->C() with pBase = &derived...
Derived::CSo -
Derived
overrides theA()
andC()
fromBase
and inheritsB()
fromBase
. The difference between overriding virtual and non-virtual methods is demonstrated inVirtualTest
- when you have a pointer tobase
,Base::A()
gets called becauseA()
is non-virtual, whereas the implementation ofC()
that is called depends on the actual type of the object that is pointed to, not the type of the pointer.My error, I got myself confused. Everything is working correctly. I had gotten confused with constructors that call the base class constructor. I re-declared everything and explicitly called the base class method.