I've been lots of threads on this subject but I still miss the whole picture.
Suppose I have a program structure like this and I want to build the project as a shared library:
class Parent
{
public:
virtual double foo1() =0;
virtual double foo2() =0;
double foo3();
}
class Daughter1 : public Parent
{
public:
double foo1();
double foo2();
}
class Daughter2 : public Parent
{
public:
double foo1();
double foo2();
}
class evenmorecomplex:
{
public:
evenmorecomplex(const &Parent);
//
}
in lots of threads, I saw there is a declaration of
extern "C"
{
//functions for which I want to prevent the mangling
}
So my problem is double:
1) doesn't this method trash all the C++ object design?
2) obviously I can't declare two identical functions in the same scope...so, how can I export all the methods in this case?
Thanks everyone will make me things clearer.
[EDIT] Some more questions...just to understand better (sorry but I'm still a newbie in C++)...
3) if I had a non-virtual method (say foo3() ) in Parent, should I export also the Parent class, or the inherited (non-virtual) foo3 will be automatic "captured" while exporting Daughter1 and Daughter2? Should I selectively export that method in the Parent class?
4) suppose Parent is called in the constructor of another class (as reference)...since Parent can't be initialized the point is making the constructor to accept both Daughter1 and Daughter2. The question is: if I export only Daughter1 and Daughter2 (and evenmorecomplex) will this constructor still work?
This is compiler specific.
extern "C" is only useful when you want to export functions C style, if you want to export functions C style you won't be able to export functions with C++ calling conventions (such as any class functions)
On Windows / Visual-Studio, simply prefix your class with __declspec( dllexport ) when exporting or __declspec( dllimport ) when importing, like this:
class __declspec( dllexport ) MyClass{
float somefloat = 12.0f;
void fucn();
}
http://msdn.microsoft.com/en-us/library/81h27t8c.aspx
To use the same header, for both importing and exporting the class, you probably want to create a define/macro.
EDIT:
3&4, All base classes must be exportable, you can not inherit an exportable class from an non-exportable class. Its described in more detail here: http://msdn.microsoft.com/en-us/library/81h27t8c.aspx
Functions exported from an library outside of an "extern "C"" block like this are not callable from any language besides C++.
If you want to be able to call the functions from a different language, you either have to only export C functions, or export a COM interface.
Related
I'm trying to use interface classes and I have the following class structure:
IBase.h:
#pragma once
class IBase
{
protected:
virtual ~IBase() = default;
public:
virtual void Delete() = 0;
IBase& operator=(const IBase&) = delete;
};
IQuackable.h:
#ifndef IQUACKABLE
#define IQUACKABLE
#include "IBase.h"
#include <iostream>
class IQuackable : public IBase
{
protected:
IQuackable() = default;
~IQuackable() = default;
public:
virtual void Quack() = 0;
static IQuackable* CreateInstance();
};
#endif //
MallardDuck.h:
#pragma once
#include "IQuackable.h"
class MallardDuck : public IQuackable
{
private:
MallardDuck();
protected:
~MallardDuck();
public:
void Delete() override;
void Quack() override;
friend IQuackable* IQuackable::CreateInstance();
};
MallardDuck.cpp:
#include "MallardDuck.h"
MallardDuck::MallardDuck() {}
MallardDuck::~MallardDuck() {}
void MallardDuck::Delete() { delete this; }
void MallardDuck::Quack()
{
std::cout << "Quack!\n";
}
IQuackable* IQuackable::CreateInstance()
{
return static_cast<IQuackable*>(new MallardDuck());
}
Also I've created class RedHeadDuck.h and .cpp with the same declaration and definition as MallardDuck.
And, finaly, main class code:
#include "MallardDuck.h"
#include "RedHeadDuck.h"
int main()
{
IQuackable* mallardDuck = MallardDuck::CreateInstance();
IQuackable* redHeadDuck = RedHeadDuck::CreateInstance();
mallardDuck->Quack();
redHeadDuck->Quack();
}
And here I got two errors:
LNK2005 "public: static class IQuackable * __cdecl IQuackable::CreateInstance(void)" (?CreateInstance#IQuackable##SAPAV1#XZ) already defined in MallardDuck.obj".
LNK1169 "one or more multiply defined symbols found".
As I find out, the problem is in double definition, but how it fix?
I've read about Header guards, but, as I understood, it can't help in this case. Also people write about inline functions, but I've not realized how it may be used here.
What can I do?
Goals
I suppose these are what you are trying to obtain by adopting all the complicated patterns:
interface, i.e., "multiple types, same set of methods"
some sort of abstract factory pattern, i.e., you want a "instantiator" who provides a static method (which is not very different from a global function) to call, and returns instances of derived classes
prohibit users from directly calling the ctors of derived classes
take care of the dtors by implementing the Delete() method
Requirement 1-3
There are at least 3 ways to meet requirement 1-3, as explained below:
1. Derived classes hiding static method of their base
This is the easiest way, and it's fully capable of current main.cpp. Derived classes can override static methods of their base class.
In file MallardDuck.h and RedHeadDuck.h:
// Replace this:
// friend IQuackable* IQuackable::CreateInstance();
// With this:
static IQuackable* CreateInstance();
In file MallardDuck.cpp (and RedHeadDuck.cpp similarly):
// Replace this:
// IQuackable* IQuackable::CreateInstance() {
// return static_cast<IQuackable*>(new MallardDuck());
// }
// With this:
IQuackable* MallardDuck::CreateInstance() {
return new MallardDuck();
}
The problem with this is that: other derived classes that don't override and hide CreateInstance() will still expose IQuackable::CreateInstance() as a "fallback". Thus:
if you don't actually implement IQuackable::CreateInstance() (so far, you don't have to), then once it is called via a derived class, the code won't compile and won't give a reason that's comprehensible to others; or
if you choose to implement it, you'd better throw an exception within it, which may surprise your user; otherwise you would have to return a nullptr or something, which is the worst practice in C++ (that's what we do in C since it has no language-level support for error handling; any C++ function that cannot fulfill its job should never return).
Either way is not elegant.
2. Adopt abstract factory pattern
This pattern requires a cooperating "factory class", which is abstract; then whenever you derive a concrete quackable, derive also its factory.
In your case you'll need to sketch out a IQuackableFactory, exposing IQuackableFactory::CreateInstance(), then derive a MallardDuckFactory and a RedHeadDuckFactory.
There are plenty of good examples already, so I won't demonstrate here.
3. Feature injection by using CRTP
There's yet another way of doing things. By CreateInstance() you're actually providing a "Give me an instance of this class!" feature. Typically we use the CRTP (curiously recurring template pattern) to "inject" a certain feature into a class.
First write this file EnableCreateInstance.hpp:
#ifndef _ENABLECREATEINSTANCE_HPP_
#define _ENABLECREATEINSTANCE_HPP_
template <class T>
struct EnableCreateInstance {
static T* CreateInstance() { return new T(); }
};
#endif //_ENABLECREATEINSTANCE_HPP_
Then in MallardDuck.h:
// Add:
#include "EnableCreateInstance.hpp"
class MallardDuck : public IQuackable, public EnableCreateInstance<MallardDuck> {
private:
MallardDuck();
friend class EnableCreateInstance<MallardDuck>;
...
In file RedHeadDuck.h do the similar: include header, publicly inherit EnableCreateInstance<RedHeadDuck>, and declare EnableCreateInstance<RedHeadDuck> as friend class.
This provides more flexibility: you're still providing an interface CreateInstance(), but in a less "aggressive" way: derived classes have their freedom to choose whether or not to provide CreateInstance(). If they do, just inherit and (if ctor made private) declare friendship; if not, omit the additional inheritance.
Requirement 4
Well, actually you can use delete this in non-static non-dtor method. But:
You must ensure (which can be difficult) that no more access to the deleted object's data members or virtual functions are made, otherwise it causes undefined behaviors;
You leave your users with dangling pointers to the deleted object.
So, we seldom provide such "deleters" in modern C++. You can get all the benefits it may provide through smart pointers, plus the ability to avoid UBs and so much more.
I am making a c++ dll which I exports a simple class from it. In the target program I make multiple objects of that class in multiple threads. I have another class inside the dll which is not exported nor declared in the exported class. I declared the hidden class in a cpp file (which has the functions in it) and initialized it in constructor of the main class. The code below, demostrate my explaination:
#define DllExport __declspec( dllexport )
class class_1
{
public:
DllExport class_1();
DllExport ~class_1();
DllExport int function_1(unsigned char* input);
};
Above code was in "mydll.h" file that I export. In a "mydll.cpp" file I defined function_1 and also declared another class like this:
class class_2
{
public:
class_2();
~class_2();
int function_2(int a);
};
class_2 will be initialize in the constructor of class_1. When in the target project I make multiple objects of class_1 and use them in different threads, the class_2 object is "common" and when 2 threads are using class_1 objects, They access to only one class_2 object, simultaneously so the program crashes.
Where and how should I declare and initialize class_2 in the dll for avoiding threads conflicting?
Options:
Make your instance of class_2 thread_local. One will exist per-thread. This can act surprising if your class_1 accesses class_2 instance in different threads.
Add a pImpl to class_1 that points to an opaque class_2.
So:
class class_2;
class class_1 {
std::unique_ptr<class_2> pImpl;
public:
DllExport class_1();
DllExport ~class_1();
DllExport int function_1(unsigned char* input);
};
As ~unique_ptr<class_2> is only called within ~class1, this is safe.
I have a library which I'm porting to Windows/MSVC. The library is C++, and uses the following pattern to hide the implementation. I'm trying to use the suggested way to export the entire class with dllexport on the class declaration.
#define API __declspec(dllexport)
class API Something
{
public:
static Something * instantiate();
void doSomething() = 0;
// etc
};
Then there is a private implementation which implements the static factory method and all the other methods.
// SomethingImpl.h
class SomethingImpl : public Something
{
//... normal overrides
}
// SomethingImpl.cpp
Something * SomethingImpl::instantiate()
{
return new SomethingImpl();
}
void SomethingImpl::doSomething()
{
// something great
}
However when I think link the DLL to my application, all these symbols are not found by the linker (LNK2019). I suppose that because they are pure virtual methods it assumes they are not needed? Any hints?
The other more normal classes are linking OK, and when I see the DLL in dependency walker, the symbols are definitely not there for these classes.
Thanks
Your assumption is correct in the sense, that the base class (Something) is not exported. More specifically, there is no actual code generated for the base class (since it is a pure virtual class). Hence there are no symbols that could be exported.
On the derived class (SomethingImpl) however you have to dllexport the private implementation for the consumer of the dll. The dllexport of the base class is not inherited by the derived class. But you have to export these symbols in order of allowing a consumer actually using this code. That does not mean your implementation details become "public" to the consumer.
As an example, imagine a consumer of your dll declares a class with a member of type Something. When this class calls Something::instantiate(), the linker needs to know which actual address needs to be called. Hence your implementation must be exported.
So, I am willing to structure my project like that:
ClassA.cpp:
class ClassA {
public:
static ClassA* create() {
return new ClassA();
}
void methodA() {
// stuff here
}
void methodB() {
// more stuff here
}
private:
ClassA() {
}
void privateMethodOne() {
//yadda yadda
}
int attributeA;
char attributeB;
};
ClassA.hpp:
class ClassA {
public:
ClassA* create();
void methodA();
void methodB();
private:
ClassA();
};
I am going to work only with pointers, I wonder if this approach would generate an error in a future. I wonder if there is a pitfall here. Suppose that the .hpp is automatically generated so it would have exactly the same members, except the private ones.
This approach is not valid. C++ has the one definition rule. See C++03 section 3.2 for full details, but here is Wikipedia's summary (highlighting is mine):
In short the ODR states that:
In any translation unit, a template, type, function, or object can have no more than one definition. Some of these can have any number of declarations. A definition provides an instance.
In the entire program, an object or non-inline function cannot have more than one definition; if an object or function is used, it must have exactly one definition. You can declare an object or function that is never used, in which case you don't have to provide a definition. In no event can there be more than one definition.
Some things, like types, templates, and extern inline functions, can be defined in more than one translation unit. For a given entity, each definition must be the same. Non-extern objects and functions in different translation units are different entities, even if their names and types are the same.
You may be looking for the PIMPL idiom, which is a way to "hide" private members from the public interface (i.e. the public header file).
As the OP expressed a wish to:
"...hide the private attributes so you dont have to deploy new headers if the amount of attributes changes"
then I would solve this by seperating interface from implementation. You expose the interface and hide the implementation.
What you could expose to those needing to use the class is a thin interface instead of a class declaration. A thin interface in C++ is best described with pure virtual functions. You would also expose a function which returns the object that implements this interface.
Firstly the header file which exposes your API. This is all the users of the service will see:
struct Interface1 {
virtual ~Interface1() {}
virtual void methodA()=0;
};
Interface1* createInstanceOfInterface1();
Then in files that the user of your service does not see we have the implementation:
class Interface1Impl : public Interface1 {
private:
int nTopSecretMemberVar;
public:
virtual void methodA() {
//implement it
}
};
Interface1* createInstanceOfInterface1() {
return new Interface1Impl();
}
And the usage of your API by the peoplse using the service who are not exposed to the details of the implementation, as follows:
void test() {
Interface1* p = createInstanceOfInterface1();
p->methodA();
}
This becomes a particularly valuable practice when it makes sense to place the implementation of such services in DLLs or shared libraries that can be plugged and played at run time. It yields many benefits.
This is actually double definition of class A
After reading this article: Using Interfaces in C++
I have decided to use the __interface keyword with a macro that will add virtual destructors as described in the above link.
I was happy that the __interface keyword will cause the compiler to enforce interface rules, but I was disappointed when I took it for a test drive... It turns out that the __interface keyword does not enforce the rule that a method in the interface should not contain a method body.
I can of course add a macro for function methods but I don't want to do this. Does anyone have any other suggestions?
EDIT: portability is a none issue for me because i must compile on both windows and linux so i will use the __interface keyword when i'm on windows and not on linux , that will be in order to enforce the below rules , which can't be enforced via abstract base class:
Can inherit from zero or more base interfaces.
Can only contain public, pure virtual methods.
Cannot contain data members; properties are allowed.
Cannot inherit from a base class.
Cannot contain constructors, destructors, or operators.
Cannot contain static methods.
besides the destructor issue which can be workaround one can see the advantage of using this keyword in windows env of course.
There is no interface keyword in Standard C++ as in Java, What you have in C++ are Abstract Base Classes.
An Abstract Base Class is a class which has atleast one pure virtual function and an object of such a class cannot be created but a pointer or reference to it can be created. Thus it can be used to simulate the behavior of interfaces.
Example of Abstract class as an interface
class Shape
{
public:
virtual void draw()=0;
};
class Rectangle:public Shape
{
public:
void draw()
{
//draw a Rectangle
}
};
int main()
{
Shape *ptr = new Rectangle();
ptr->draw(); //calls draw() of Rectangle class
return 0;
}
Note that:
__interface keyword as a new Microsoft extension to the C++ compiler.
That is non C++ Standard specified and Non portable.
EDIT: This answer was to a question titled "__interface keyword Win c++" and was tagged C++.
__interface is a microsoft specific extension. It's not standard and not portable.
Also, C++ allows for pure virtual method to have function body.
class Base {
virtual void foo () = 0;
};
void Base::foo ()
{ } // ok
It's advisable to explicitly declare virtual destructor in the class body.