I have recently run into this problem when using NVI with a template base class across compilation different units. If I have two classes deriving from my base class with the same template argument (but differing behavior), I get a multiple symbol definition error for HandleData(), the indirection method in the base class.
Additionally marking HandleData() as inline did not change the error. Inclusion guards are in place and correct.
I'm grateful for any and all ideas!
Update:
The main problem appears to be the template instantiation: If I put both unit tests into the same file, they run correctly - the problems appears only if derived classes are instantiated in different files (compilation units) of the same DLL (UnitTest.dll, I happen to use CPPUnit btw.)
Base class (in DLL X):
template <class DataType>
class cDataHandlerBase
{
public:
virtual ~cDataHandlerBase();
bool HandleData(const std::vector<DataType>& data)const
{
return doHandleData(data);
}
protected:
cDataHandlerBase();
private:
virtual bool doHandleData(const std::vector<DataType>& data)const = 0;
};
Derived classes (in DLL Y, files A and B):
class cDataHandlerA : public cDataHandlerBase<SomeType>
{
virtual bool doHandleData(const std::vector<DataType>& data)const override;
};
class cDataHandlerB : public cDataHandlerBase<SomeType> //same type as cDataHandlerA!
{
virtual bool doHandleData(const std::vector<DataType>& data)const override;
};
UnitTest-DLL contains files TestA and TestB, upon compiling these I get multiple definitions of cDataHandlerBase::HandleData().
Related
This is the first time I am using class templates so please don't be to harsh if I made a simply mistake.
I have a class template class A<class T>. It has a method init() that is pure virtual and therefore will be implemented separately in every derived class. What all these possible derived classes will have in common is an init(T* i_x) which basically does some general stuff and then calls the init(). Because this will be the same for every derived class I want to define it in the base class template already. But somehow my compiler doesn't find the right function.
If I try to use the init(T* i_x) on an object of a derived class A_der I get the error:
no matching function for call to 'A_der::init(B_der*)
The classes used for the template parameter T will all be derived from another class B. Therefore the error message involves the class B_der which is derived from class B.
I boiled the problem down to a small example, which should involve everything that is important for the problem. If I try to compile this example in Visual Studio (normally I work in STM32CubeIDE) I get the following error
Severity Code Description Project File Line Suppression State
Error C2660 'A_der::init': function does not take 1
arguments template_class-overload_inherited_method [...]\main.cpp 8
So somehow the only function the compiler finds at this point is init() but not the base class template method init(T* ).
Can somebody please tell me why it is like that and what can I do to get the behaviour I want (without implementing a similar init(T* ) in every derived class of A?
Here is my example code:
base class template A - declaration - A.hpp
template<class T>
class A
{
protected:
T* m_x;
public:
virtual void connect(T* i_x) final;
virtual void init() = 0;
virtual void init(T* i_x) final;
};
base class template A - implementation - A.cpp
#include "A.hpp"
template<class T>
void A<T>::connect(T* i_x)
{
//some checks
m_x = i_x; //connects object of B to A
}
template<class T>
void A<T>::init(T* i_x)
{
connect(i_x);
init();
}
derived class A_der
#include "A.hpp"
#include "B_der.hpp"
#pragma once
class A_der : public A<B_der>
{
void init() override;
};
void A_der::init()
{
//Initialization which needs a B_der connected already
}
main.cpp
#include "B_der.hpp"
#include "A_der.hpp"
int main(void)
{
B_der testB;
A_der testA;
testA.init(&testB);
return 0;
}
For the sake of completeness:
class B
{
};
class B_der : public B
{
};
EDIT - Solved
Thanks a lot for the fast replies.
The combination of the comments from #BoP and #Jarod42 solved the problem.
I had to unhide the method with using A<B_der>::init (actually renaming might be the more elegant way) and move the implementation of A into A.hpp.
I will offer the updated example which builds successfully with Visual Studio 2019 for me here:
base class A
template<class T>
class A
{
protected:
T* m_x;
public:
virtual void connect(T* i_x) final;
virtual void init() = 0;
virtual void init(T* i_x) final;
};
template<class T>
void A<T>::connect(T* i_x)
{
//some checks
m_x = i_x; //connects object of B to A
}
template<class T>
void A<T>::init(T* i_x)
{
connect(i_x);
init();
}
derivad class A_der
A_der.hpp
#include "A.hpp"
#include "B_der.hpp"
class A_der : public A<B_der>
{
public:
void init() override;
using A<B_der>::init;
};
A_der.cpp
#include "A_der.hpp"
void A_der::init()
{
//Initialization which needs a B_der connected already
}
main.cpp
#include "B_der.hpp"
#include "A_der.hpp"
int main(void)
{
B_der testB;
A_der testA;
testA.init(&testB);
return 0;
}
for completeness
B.hpp
class B
{
};
B_der.hpp
#include "B.hpp"
class B_der : public B
{
};
I also forgot to make the methods of A_der public in the earlier example, this is corrected here. And I removed the #pragma onces in this example.
class A_der : public A<B_der>
{
void init() override;
};
When you declare a function init in the derived class, it hides all things named init from the base class. This is just like when declaring something in an inner scope - it hides things with the same name from outer scopes.
There are ways to import the hidden names, but an easy solution would be to just chose a different name, like init_base. Or, probably better, pass a parameter to the class constructor.
The syntax of MOCK_METHOD can be used inside a class definition:
class A {
MOCK_METHOD0(f, void(void));
};
Is it possible to mock a method that has already been declared? What I want is to do something similar to:
#include "gmock/gmock.h"
class HelloTest {
void f();
};
MOCK_METHOD0(HelloTest::f, void(void));
The idea is to put the class definition in an hpp file and then the mocks in a cpp file. In effect, my class definition with its methods' prototypes needs to be in common with other cpp files in my build chain and I don't want to use virtual functions.
Unfortunately, when I try to do what I wrote above, I get the following error on the line that contains MOCK_METHOD0:
error: ‘gmock0_HelloTest’ has not been declared
What does this error mean and is there a way to do what I want?
To begin with, your MOCK_METHOD0() declaration must belong to a mock class, under a public section. For instance, your code snippet:
#include "gmock/gmock.h"
class HelloTest {
void f();
};
MOCK_METHOD0(HelloTest::f, void(void));
Should instead look like this:
#include "gmock/gmock.h"
class HelloTest {
virtual void f();
};
class Mock_HelloTest : public HelloTest {
public:
MOCK_METHOD0(f, void(void));
};
Now, you'll notice that I've changed f() to be virtual instead, since your use of HelloTest::f in MOCK_METHOD0 requires f() to be virtual.
Since you don't want to use virtual functions, your only other option is to use what the Google Mock team calls hi-perf dependency injection. With this non-virtual approach, you'd have to create a separate mock class that doesn't inherit from HelloTest. You'd also need to templatize any code that currently uses HelloTest to switch between HelloTest in production and Mock_HelloTest in tests.
As an example, let's say you have the following function that calls HelloTest::f():
void RunHelloTest() {
HelloTest HT;
HT.f();
}
You would set up your code snippet as follows:
#include "gmock/gmock.h"
class HelloTest {
void f(); // <- f is no longer virtual
};
class Mock_HelloTest { // <- Mock_HelloTest no longer inherits from HelloTest
public:
MOCK_METHOD0(f, void(void));
};
And modify RunHelloTest() to accept a template type argument:
template <class HelloTestClass>
void RunHelloTest() {
HelloTestClass HT;
HT.f(); // <- will call HelloTest::f() or Mock_HelloTest::f()
}
With this setup, you'd call RunHelloTest<HelloTest>() in your production code, and RunHelloTest<Mock_HelloTest>() in your test code.
I would like to implement the expose module in derived class (.h or .cpp file). its work fine, when I exposed this in main in one BOOST_PYTHON_MODULE but when I exposed differently in abstract and derived class its get error one or more multiply defined symbols errors. the example code is as follows.
**Base.h**
class Base
{
public:
virtual void Set(const std::vector<std::string>& AllParameters) = 0;
};
struct BaseWrap : Base, wrapper<Base>
{
void Set(const std::vector<std::string>& AllParameters)
{
this->get_override("Set")(AllParameters);
}
**Base.cpp**
BOOST_PYTHON_MODULE(Example)
{
class_<Basewrapper , boost::noncopyable> ("Base")
.def("Set",pure_virtual(&Base::Set))
;
}
**Derived.h**
class Derived : public Base
{
public:
int test(int a, int b);
};
BOOST_PYTHON_MODULE(Example)
{
class_<Derived , boost::noncopyable> ("Derived")
.def("test",&Derived ::test)
;
}
**Derived.cpp**
void Derived:: test(int a , int b)
{
return a+b;
}
The BOOST_PYTHON_MODULE macro defines a function with identifiers based on the provided argument. Hence, defining the Example module in both Base.cpp and Derived.h violates the one definition rule when linking them into the same library. To resolve this, consider splitting the function bodies that export each individual class into their own functions (i.e. export_base() and export_derived()), and have a single file (example.cpp) that defines BOOST_PYTHON_MODULE with a body that invokes the other export functions. This technique can be seen here.
I am writing a shared library (call it MyLib) which depends on another library (call it ParentLib). The ParentLib has a few virtual functions which I am implementing in MyLib along with several other independent implementations.
// MyLib.h
#include <parentlib_library.h>
class Foo : public ClassinParent
{
public:
void DefinitionofParentLibFunction();
private:
// ...
};
I was able to compile and generate the MyLib with no issues but when the MyLib is used by the application, I need to include the ParentLib_library.h to compile the code.
One of my requirements is that the ParentLib should be completely hidden from the application. I am not sure of the next step to achieve this.
Any ideas?
If your declaration used in callback or implementation of interface from 3dparty lib - then no way. In all another cases I usually apply following 3 approaches.
1) Use aggregation. Declare ClassInParent as forward and use as member of Foo:
class ClassInParent;//forward declare
class Foo
{
ClassInParent* _inst; //use either pointer of reference to external
public:
void method_of_ClassInParent() //make facade for parent methods if needed
}
2) Separate your class into interface (that is not depended on ClassInParent) and implementation (that is not expose via #include)
Your Foo.h:
class Foo
{
public:
virtual void do_smth() = 0;
};
Your Foo.cpp:
#include <parentlib_library.h>
class FooImpl : public Foo, public ClassInParent
{
void do_smth()
{//implementation
3) Use templates. Instead of explicit inherience use template:
template <class T>
class Foo : public T
{
Later in your code Foo<ClassInParent>
if i want to have 3 classes, which have common fields (and i want them to be static)
and they have a common function (which needed to be overridden, i.e virtual)
what the best design to do this?
do i need to create an interface in a header file
and then create it's .cpp file and get the 3 classes inheritance from it?
what about the static members?
can i declare them in the header file?
when creating header file which representing interface, do i have to create it's .cpp file?
Declare the classes in header files.
This is so that the declaration can be shared between multiple source files (with #include) and thus obey the (One definition rule).
It is traditional (though not required) that each class has its own file. To make it consistent and easy to find things you should name the file after the class. So Class A should be declared in A.h and defined in A.cpp.
MyInterface.h
class MyInterface
{
protected:
static int X;
static int Y;
static int Z;
public:
// If a class contains virtual functions then you should declare a vritual destructor.
// The compiler will warn you if you don't BUT it will not require it.
virtual ~MyInterface() {} // Here I have declared and defined the destructor in
// at the same time. It is common to put very simplistic
// definitions in the header file. But for clarity more
// complex definitions go in the header file. C++ programers
// dislike the Java everything in one file thing because it
// becomes hard to see the interface without looking at the
// documentaiton. By keeping only the declarations in the
// header it is very easy to read the interface.
virtual int doSomthing(int value) = 0; // Pure virtual
// Must be overridden in derived
};
A.h
#include "MyInterface.h"
class A: public MyInterface
{
public:
virtual int doSomthing(int value);
};
B.h
#include "MyInterface.h"
class B: public MyInterface
{
public:
virtual int doSomthing(int value);
};
C.h
#include "MyInterface.h"
class C: public MyInterface
{
public:
virtual int doSomthing(int value);
};
Now you define the implementation in the source files:
MyInterface.cpp
#include "MyInterface.h"
// Static members need a definition in a source file.
// This is the one copy that will be accessed. The header file just had the declaration.
int MyInterface::X = 5;
int MyInterface::Y = 6;
int MyInterface::Z = 7;
A.cpp
#include "A.h"
// Define all the methods of A in this file.
int A::doSomthing(int value)
{
// STUFF
}
B.cpp
#include "B.h"
int B::doSomthing(int value)
{
// STUFF
}
C.cpp
#include "C.h"
int C::doSomthing(int value)
{
// STUFF
}
There is no explicit "interface" thing in the C++ language.
If you'd like to have an interface-like class, that's a class with pure virtual methods (that is a method w/o definition, e.g. virtual void printme() = 0;).
Static variables are bound to object files (internal linkage). If you define them in your header file and include that header file into several cpp files, you'll end up having several definitions of that static variable (in different object files)
Since static variables are either global or part of a class, they cannot be 'common'. They belong to one class and may be accessed by another one.
Same goes for methods. One class has a method, another one may call it. If it's a derived class, it may also override it (that is either hide it or implement a virtual method).
Now, if you have three classes that have the same structure, you may (or may not) like to inherit them from a base class for several reasons. One is to avoid copying code. Another one is the main reason, that you may want to treat objects from the derived classes all the same, let's say you have a vehicle that you can use, but the vehicle may be a car, a bike or a plane. You want to use a vehicle, but don't mind which vehicle it actually is, so you create
class Vehicle
{
public:
virtual void use() = 0;
};
class Car
: public Vehicle
{
public:
virtual void use();
};
void Car::use()
{
// drive the car
}
Than you can use a Car as vehicle, for example
Car myCar;
Vehicle& myVehicle = static_cast< Vehicle& >(myCar);
myVehicle.use(); // drive the car.
That all is fundamental C++ OOP, look it up in some book.