Here is the header file defining the template:
Based on a few answers, I made modifications to make template single thread safe. But the program still crashes, so I believe the focus here should not be if the template is thread safe. It's about what happened when C1 inherits from both CBase and Singleton. Apparently, the program crashes when C1 is trying to call the function of the member variable it's parent Class CBase. It seems to me, something is messed up in the memory when multiple inheritance and the single template are used together.
#ifndef _T_SINGLETON_HH_
#define _T_SINGLETON_HH_
template <class T>
class Singleton
{
public:
static T* getInstance()
{
static T instance_;
return &instance_;
}
template <class A>
static T* getInstance(A a)
{
static T instance_(a);
return &instance_;
}
protected:
Singleton() {}
virtual ~Singleton() {}
private:
Singleton(Singleton const&);
Singleton& operator=(Singleton const&);
};
#endif // _T_SINGLETON_HH_ //
And here is how this template was used:
#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include "singleton.hh"
using namespace std;
class X;
class X1;
class ABase;
class BBase;
class BB;
class CBase;
class X {
public:
virtual int getX() = 0;
};
class X1 : public X {
public:
int getX() { return 1; }
};
class Timer
{
private:
static Timer* t_;
BBase* b_;
Timer();
static void* go_helper(void* context);
void go();
public:
virtual ~Timer() {}
static Timer* getInstance();
void subscribe(BBase* b);
void unsubscribe(BBase* b) { b_ = NULL; }
};
class CBase {
public:
CBase(BB& bb) : bb_(bb) {}
virtual void run() = 0;
protected:
BB& bb_;
};
class C1 : public CBase,
public Singleton<C1>
{
public:
C1(BB& bb) : CBase(bb) {}
void run();
};
class BBase {
public:
BBase(ABase& a) : a_(a) { Timer::getInstance()->subscribe(this); }
virtual ~BBase() { Timer::getInstance()->unsubscribe(this); }
virtual void run() = 0;
protected:
ABase& a_;
};
class BB : public BBase {
public:
BB(ABase& a) : BBase(a) {
c = C1::getInstance(*this);
// c = new C1(*this); IF WE USE THIS INSTEAD, THEN IT WILL WORK
}
int getX();
void run();
private:
CBase* c;
};
class ABase {
public:
ABase() {
x = new X1;
b = new BB(*this);
}
void run();
int getX() { return x->getX(); }
private:
X* x;
BBase* b;
};
Timer* Timer::t_ = NULL;
Timer::Timer() : b_(NULL)
{
pthread_t th;
pthread_create(&th, NULL, &Timer::go_helper, this);
}
Timer*
Timer::getInstance() {
if (t_ == NULL)
t_ = new Timer;
return t_;
}
void
Timer::subscribe(BBase* b) { b_ = b; }
void*
Timer::go_helper(void* context) {
Timer *t = reinterpret_cast<Timer*>(context);
t->go();
return NULL;
}
void
Timer::go()
{
while(1) {
sleep(1);
if (b_) b_->run();
}
}
void ABase::run() {
cout << __PRETTY_FUNCTION__ << getX() << endl;
cout << __PRETTY_FUNCTION__ << x->getX() << endl;
b->run();
while(1)
sleep(1);
}
int BB::getX() {
return a_.getX();
}
void BB::run() {
cout << __PRETTY_FUNCTION__ << endl;
c->run();
}
void C1::run() {
cout << __PRETTY_FUNCTION__ << bb_.getX() << endl;
}
int main()
{
ABase* a = new ABase;
a->run();
}
If you still think it is a thread safe issue, then here is the simplified one thread version using the template:
#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include "singleton.hh"
using namespace std;
class X;
class X1;
class ABase;
class BBase;
class BB;
class CBase;
class X {
public:
virtual int getX() = 0;
};
class X1 : public X {
public:
int getX() { return 1; }
};
class CBase {
public:
CBase(BB& bb) : bb_(bb) {}
virtual void run() = 0;
protected:
BB& bb_;
};
class C1 : public CBase,
public Singleton<C1>
{
public:
C1(BB& bb) : CBase(bb) {}
void run();
};
class BBase {
public:
BBase(ABase& a) : a_(a) { }
virtual ~BBase() { }
virtual void run() = 0;
protected:
ABase& a_;
};
class BB : public BBase {
public:
BB(ABase& a) : BBase(a) {
c = C1::getInstance(*this);
// c = new C1(*this);
}
int getX();
void run();
private:
CBase* c;
};
class ABase {
public:
ABase() {
x = new X1;
b = new BB(*this);
}
void run();
int getX() { return x->getX(); }
private:
X* x;
BBase* b;
};
void ABase::run() {
cout << __PRETTY_FUNCTION__ << getX() << endl;
cout << __PRETTY_FUNCTION__ << x->getX() << endl;
b->run();
while(1)
sleep(1);
}
int BB::getX() {
return a_.getX();
}
void BB::run() {
cout << __PRETTY_FUNCTION__ << endl;
c->run();
}
void C1::run() {
cout << __PRETTY_FUNCTION__ << bb_.getX() << endl;
}
When I run this program, it crashes:
void ABase::run()1
void ABase::run()1
virtual void BB::run()
zsh: segmentation fault (core dumped) ./a.out
Here is the stack information given by GDB:
#0 0x00000000004012ba in ABase::getX (this=0x1) at tst_sigill.cc:89
89 int getX() { return x->getX(); }
[Current thread is 1 (Thread 0x7faa0f050740 (LWP 5351))]
(gdb) bt
#0 0x00000000004012ba in ABase::getX (this=0x1) at tst_sigill.cc:89
#1 0x0000000000400e0c in BB::getX (this=0x7ffed6e821f0) at tst_sigill.cc:138
#2 0x0000000000400e71 in C1::run (this=0xaeedd0) at tst_sigill.cc:146
#3 0x0000000000400e51 in BB::run (this=0xaeec60) at tst_sigill.cc:142
#4 0x0000000000400de3 in ABase::run (this=0xaeec20) at tst_sigill.cc:132
#5 0x0000000000400ed1 in main () at tst_sigill.cc:152
For some unknown reason, this pointer passed to BB::getX and ABase::getX was messed up. I can't see what's wrong with the code.
Well, the major problem seems to be that your getInstance() implementation isn't thread safe.
I'd recommend forgetting about all that construct() / destruct() stuff also and simply leave that to the CRT0 code provided with the ABI.
You should rather use an implementation following the Scott Meyer's Singleton that is guaranteed to be thread safe (at least for the current standard):
template <class T>
class Singleton {
public:
static T& getInstance() {
static T instance_;
return instance_;
}
protected:
Singleton() {}
virtual ~Singleton() {}
Singleton(Singleton const&) = delete;
Singleton& operator=(Singleton const&) = delete;
};
If there's need to change any of the Singletons properties later that could be accessed asynchronously, keep in mind to provide thread safe operations as well.
You could support that with your template singleton base like:
template <class T>
class Singleton {
// ...
protected:
mutable std::mutex internalDataGuard;
};
class C1 : public CBase, public Singleton<C1> {
public:
C1(BB& bb) : CBase(bb) {}
void run();
void setSomeData(T data) {
std::unique_lock(Singleton<C1>::internalDataGuard);
// change internal data member ...
}
const T& getSomeData() const {
std::unique_lock(Singleton<C1>::internalDataGuard);
// return internal data member ...
}
};
A quick note on using the stack trace to pick off some useful information. The program crashes where it crashes, but sometimes the trace can give you a few hints on where things started to go wrong:
#0 0x00000000004012ba in ABase::getX (this=0x1) at tst_sigill.cc:89
Died here. this=0x1, says that this is pointing to nonsense; 0x1 is almost certainly an invalid memory location. I can't think of a modern platform where 1 is valid memory. Doesn't mean there isn't one, but it's highly unlikely and thus a suspect.
#1 0x0000000000400e0c in BB::getX (this=0x7ffed6e821f0) at tst_sigill.cc:138
Here this is questionable. Skipping down over the next few lines, we see that all of the this pointers are in and around 0xaeeXXX. 0x7ffed6e821f0 is pretty far out there, so we should start by looking at references to BB
#2 0x0000000000400e71 in C1::run (this=0xaeedd0) at tst_sigill.cc:146
Specifically those inside C1 since it was the last object we were in with a sane address.
Maybe the rest of the stack trace matters, maybe it doesn't. Maybe we'll get back to it for more clues, but for the moment let's run down the current leads.
Looking in on C1, I see:
C1(BB& bb) : CBase(bb) {}
Takes a BB reference and passes it to CBase's constructor
CBase(BB& bb) : bb_(bb) {}
Stores the BB in bb_
So where does the BB come from? C1 is instantiated by the singleton. I don't see any calls to construct, so this leaves getInstance(A a), which does not take a reference. This means C1(BB& bb) is called with a temporary. The temporary is ultimately stored in CBase::bb_ which is a BB&, so bb_ is a reference to a variable that will no longer exist after returning from getInstance. Attempting to use bb_ after this point will invoke Undefined Behaviour.
I am not going to suggest a fix for this because this code is too convoluted for it's own good and, as πάντα ῥεῖ points out in his answer, isn't going to work without a significant redesign.
Related
I have two classes B andY which I cannot change or edit by requirement. They have functions doing the same thing but with different names.
I want to a have a common interfaces with selecting the class at run time depending on the some input variable as described in the code below. I am not sure which design pattern should I use. How to create WrapperYB class which selects Y::show or B::showing depending on the object created.
class A
{
public:
A() {}
virtual ~A();
virtual void show() { cout << "show A" << endl;}
};
class B:A
{
public:
B() {}
virtual ~B();
virtual void show() { cout << "show B" << endl;}
};
class X
{
char m_i;
public:
Y() { m_i = 'X';}
virtual void showing() { cout << "showing " << m_i << endl;}
};
class Y:X
{
public:
Y() { m_i = 'Y';}
virtual void showing() { cout << "showing " << m_i << endl;}
};
class WrapperYB
{
// to be implemented
public:
explicit WrapperYB(const int& type);
void show();
};
int main(){
WrapperYB objY(1);
objY.show(); // must call Y::showing
WrapperYB objB(0);
objB.show(); // must call B::show
}
If your compiler supports the C++17 Standard, you could try this solution using std::variant. This is a similar idea to the solution in #Nicolas's answer, but variant will take care of the implementation details for you, won't use dynamic memory allocation, and has support for additional things like copy and assignment.
#include <variant>
#include <utility>
#include <type_traits>
class WrapperYB {
public:
using variant_type = std::variant<Y, B>;
template <typename... Args,
std::enable_if_t<std::is_constructible_v<variant_type, Args...>>* = nullptr>
WrapperYB(Args&& ... args) : m_variant(std::forward<Args>(args)...) {}
variant_type& variant() noexcept { return m_variant; }
const variant_type& variant() const noexcept { return m_variant; }
void show()
{ std::visit(ShowImpl{}, m_variant); }
private:
struct ShowImpl {
void operator() (Y& y) const { y.showing(); }
void operator() (B& b) const { b.show(); }
};
variant_type m_variant;
};
See the full working example on coliru.
You might generalize the wrapper by letting it contain a std::unique_ptr<A> or std::unique_ptr<X> instead.
I'm proposing this:
#include <iostream>
using namespace std;
class A
{
public:
A() {}
virtual ~A() {}
virtual void show() { cout << "show A" << endl;}
};
class B:A
{
public:
B() {}
virtual ~B() {}
virtual void show() { cout << "show B" << endl;}
};
class X
{
protected:
char m_i;
public:
X () { m_i = 'X';}
virtual void showing() { cout << "showing " << m_i << endl;}
};
class Y:X
{
public:
Y() { m_i = 'Y';}
virtual void showing() { cout << "showing " << m_i << endl;}
};
class WrapperYB
{
public:
enum class Which { B, Y };
public:
explicit WrapperYB (int n)
: which(Which(n))
{
switch (which)
{
case Which::B: ptr.b = new B; break;
case Which::Y: ptr.y = new Y; break;
}
}
~WrapperYB ()
{
switch (which)
{
case Which::B: delete ptr.b; break;
case Which::Y: delete ptr.y; break;
}
}
WrapperYB (const WrapperYB&) = delete;
WrapperYB& operator = (const WrapperYB&) = delete;
public:
void show()
{
switch (which)
{
case Which::B: ptr.b->show() ; break;
case Which::Y: ptr.y->showing(); break;
}
}
private:
Which which;
union {
Y* y;
B* b;
} ptr;
};
int main(){
WrapperYB objY(1);
objY.show(); // must call Y::showing
WrapperYB objB(0);
objB.show(); // must call B::show
}
It's not a "Vanilla" design pattern, I don't think, and more of combination of adapter and discriminated union.
Note that WrapperYB cannot be copied or assigned, as is.
You can use a standard virtual dispatch method with an abstract base adaptor class and subclasses for each object type needed. Create the object with a factory method.
#include <memory>
//pre-defined structures Y, B
struct Y
{
Y(){}
~Y(){}
void show(){}
};
struct B
{
B(){}
~B(){}
void showing(){}
};
// Abstract adaptor base class.
struct Adaptor
{
virtual void show() = 0;
};
// A subclass of Adaptor for each type of object to be wrapped.
struct Adaptor_Y: Adaptor
{
Adaptor_Y(): y(){}
void show() override
{
y.show();
}
private:
Y y;
};
struct Adaptor_B: Adaptor
{
Adaptor_B(): b(){}
void show() override
{
b.showing();
}
private:
B b;
};
// Factory method constructs the proper object and returns a pointer.
std::unique_ptr<Adaptor> get_adaptor(int flag)
{
if(flag == 0)
{
return std::make_unique<Adaptor_B>();
}
else if(flag == 1)
{
return std::make_unique<Adaptor_Y>();
}
else throw std::runtime_error("Invalid flag value");
}
How can I achieve the following design using C++11:
class Consumer : Base<Consumer>
{
// different consumers will have different methods (of the same signature)
void Foo(){...}
void Bar(){...}
: // etc.
static void override
register_all () {
register_method<&Consumer::Foo>("foo");
register_method<&Consumer::Bar>("bar");
: // etc.
}
:
}
template<typename T>
class Base
{
static
Base() {
register();
}
virtual static void
register_all(){ };
using F = void(T::*)();
template<F f>
static void
register_method(std::string name) {
...
}
}
...?
Note that I'm doing two illegal things:
I am using a static constructor (not allowed) on the base class
I am using virtual static function (also not allowed)
NOTE: Registration of methods needs to occur only once, before the first instance is accessed (it will populate a static C-function-pointer table).
Finally, is there any better technique I could be using, some way of somehow tagging or marking methods that need to be registered, and save the consumer the trouble of having to manually register them in a separate function?
I believe regular CRTP will work just fine. This gets rid of both the virtual and the static. Using an std::once_flag in combination with std::call_once will allow you to only call the function once -- mimicking the effects of a 'static constructor'. It just requires a little bit of messing around.
Full Code:
#include <iostream>
#include <mutex>
template<typename T>
struct Base {
Base() {
static_cast<T*>(this)->register_all();
}
using F = void(T::*)();
template<F f>
void register_method(const char* str) {
// ...
std::cout << "registered " << str << '\n';
}
};
struct Derived : Base<Derived> {
private:
static std::once_flag flag_;
void implementation() {
register_method<&Derived::foo>("foo");
register_method<&Derived::bar>("bar");
}
public:
void foo() {}
void bar() {}
void register_all() {
std::call_once(flag_, [this]{ implementation(); });
}
};
std::once_flag Derived::flag_;
int main() {
Derived x;
Derived y;
}
Live Demo
I've modified Rapptz's answer to move all the machinery back into the base class:
http://coliru.stacked-crooked.com/a/52fd723e905333c6
#include <iostream>
#include <mutex>
template<typename T>
struct Base {
Base() {
std::call_once(flag_, T::register_all );
}
using F = void(T::*)();
template<F f>
static void register_method(const char* str) {
// ...
std::cout << "registered " << str << '\n';
}
public:
static std::once_flag flag_;
};
// have to initialise static-s outside class...
template<typename T>
std::once_flag Base<T>::flag_{};
...
struct Derived1 : Base<Derived1> {
public:
static void register_all() {
std::cout << "D1" << '\n';
register_method<&Derived1::foo>("foo");
register_method<&Derived1::bar>("bar");
}
public:
void foo() {}
void bar() {}
};
struct Derived2 : Base<Derived2> {
public:
static void register_all() {
std::cout << "D2" << '\n';
register_method<&Derived2::woot>("woot");
}
public:
void woot() {}
};
...
int main() {
Derived1 x;
Derived1 y;
Derived2 z;
}
EDIT: strangely I need to initialise my flag with {} but Rapptz didn't. Why is this?
EDIT2: this code fails on ideone, because ideone doesn't use -pthread compiler flag. Using a simpler 'static bool first=true; if(first){first = false;...} construct would do the trick as c++11 stipulates that initialisation of static variables be thread safe.
Edit: Per some comments, by simple I mean a) less code, b) easy to maintain, and c) hard to get wrong.
Edit #2: Also, using containment instead of private inheritance is not objectionable if it does indeed simplify the implementation of InterfaceImpl.
Currently, the only way I know to do this is to have the implementer define the abstract method and delegate the call to the target base type's method. Example:
#include <iostream>
#include <memory>
class Interface
{
public:
virtual void method1() = 0;
virtual void method2(int x) = 0;
};
class MethodOneImpl
{
private:
void method1(int x)
{ std::cout << "MethodOneImpl::method1() " << x << std::endl; }
public:
void method1() { method1(0); }
};
class MethodTwoImpl
{
public:
void myFunc(int x)
{ std::cout << "MethodTwoImpl::myFunc(x)" << x << std::endl; }
};
class InterfaceImpl : public Interface
, private MethodOneImpl
, private MethodTwoImpl
{
public:
virtual void method1() { MethodOneImpl::method1(); }
virtual void method2(int x) { MethodTwoImpl::myFunc(x); }
};
int main()
{
std::unique_ptr<Interface> inf;
inf.reset(new InterfaceImpl);
inf->method1();
inf->method2(0);
// This should be disallowed!
// std::unique_ptr<MethodOneImpl> moi;
// moi.reset(new InterfaceImpl);
}
At first, I thought that perhaps this might solve the problem:
class InterfaceImpl : public Interface
, private MethodOneImpl
, private MethodTwoImpl
{
public:
using MethodOneImpl::method1;
// Obviously this wouldn't work as the method names don't match.
//using MethodTwoImpl::???
};
The first using statement will make both MethodOneImpl::method1 methods be public, but it actually doesn't fulfill the contract with Interface, and it modifies the accessibility of MethodOneImpl::method1(int). And obviously we couldn't use this solution with method2 as the names don't match up.
FWIW, I have what I think is a solution, but it is not part of the standard at all (in other words it won't compile). I was thinking of making a proposal to the C++ committee; if anyone has any advice, I'd appreciate any comments below (but please dont' submit the advice as an answer).
An other option (at least if using MS VC++) is to use virtual inheritance:
struct MyInterface
{
virtual void Method1() = 0;
virtual void Method2() = 0;
};
class Method1Impl : public virtual MyInterface
{
virtual void Method1() { _tprintf( _T("Method1\n") ); }
};
class Method2Impl : public virtual MyInterface
{
virtual void Method2() { _tprintf( _T("Method2\n") ); }
};
class InterfaceImpl : public virtual MyInterface,
private Method1Impl,
private Method2Impl
{
};
void TestWeirdInterfaceImpl()
{
MyInterface* pItf = new InterfaceImpl();
pItf->Method1();
pItf->Method2();
}
While this seems to work and satisfy what you are looking for (asside from C4250 warning that you will have to suppress with a #pragma), this wouldn't be my approach. (I believe virtual inheritance is still not something that supported across all compilers, but I could be wrong).
I would probably go with containment and once boilerplate code is identifier, wrap it into some kind of macro map (similar to maps in ATL or MFC) that would make it really, really difficult to ever screw it up.
So this would be my macro approach:
struct MyInterface
{
virtual float Method1( int x ) = 0;
virtual int Method2( float a, float b ) = 0;
virtual void Method3( const TCHAR* sz ) = 0;
};
class Method1Impl
{
public:
float Method1( int x ) {
_tprintf( _T("Method1: %d\n"), x ); return 5.0;
}
};
class Method2and3Impl
{
public:
int Method2( float a, float b ) {
_tprintf( _T("Method2: %f, %f\n"), a, b ); return 666;
}
void Method3( const TCHAR* sz ) {
_tprintf( _T("Method3: %s"), sz );
}
};
#define DECLARE_METHOD0( MethodName, Obj, R ) \
virtual R MethodName() { return Obj.MethodName(); }
#define DECLARE_METHOD1( MethodName, Obj, R, A1 ) \
virtual R MethodName( A1 a1 ) { return Obj.MethodName( a1 ); }
#define DECLARE_METHOD2( MethodName, Obj, R, A1, A2 ) \
virtual R MethodName( A1 a1, A2 a2 ) { return Obj.MethodName( a1, a2 ); }
class InterfaceImpl : public MyInterface
{
public:
DECLARE_METHOD1( Method1, m_method1Impl, float, int );
DECLARE_METHOD2( Method2, m_method2and3Impl, int, float, float );
DECLARE_METHOD1( Method3, m_method2and3Impl, void, const TCHAR* );
private:
Method1Impl m_method1Impl;
Method2and3Impl m_method2and3Impl;
};
void TestWeirdInterfaceImpl()
{
MyInterface* pItf = new InterfaceImpl();
pItf->Method1( 86 );
pItf->Method2( 42.0, 24.0 );
pItf->Method3( _T("hi") );
}
Until C++ gods grace us with variadic macros, you'll have to declare one for each number of parameters you have. Also if you used multiple inheritance, potentially you wouldn't need the second "Obj" param, but as I've said before, I'd avoid multiple inheritance if there's another solution, which in this case is one extra param.
Yet a third option could be something that authors of Pragmatic Programmer seem to advocate a lot. If you have a ton of cookie cutter code that you don't want to repeat because, as you pointed out, it introduces human error. Define your own language and write a code generator script (python, perl...) to auto-create the actual code. In this case you could almost point at an interface, and have the script write the text out for you. I haven't tried doing this kind of thing myself, but lately have been wanting to use it somewhere just to see and evaluate the outcome.
This is sort of ugly and may bloat the executable size, but what about
#include <iostream>
class Interface
{
public:
virtual void method1() = 0;
virtual void method2(int x) = 0;
};
template<typename T>
class MethodOneImpl : public T
{
private:
void method1(int x)
{ std::cout << "MethodOneImpl::method1() " << x << std::endl; }
public:
void method1() { method1(0); }
};
template<typename T>
class MethodTwoImpl : public T
{
public:
void method2(int x)
{ std::cout << "MethodTwoImpl::myFunc(x)" << x << std::endl; }
};
class InterfaceImpl : public MethodTwoImpl<MethodOneImpl<Interface> >
{
};
int main()
{
InterfaceImpl impl;
impl.method1();
impl.method2(0);
}
class AbsInterface
{
// this is a simple interface class.
public:
virtual void Method1() = 0;
virtual void Method2() = 0;
};
class Functor1
{
public:
void operator () ()
{
printf("This Is Void Functor1");
}
};
class Functor2
{
public:
void operator () ()
{
printf("This Is void Functor2");
}
};
template <class T1, class T2>
class DerivedTemplateClass : public AbsInterface
{
public:
virtual void Method1() { T1()(); }
virtual void Method2() { T2()(); }
};
void main()
{
DerivedTemplateClass<Stratege1, Stratege2> instance;
instance.Method1();
instance.Method2();
}
as you can see, I used Functor.
You could work with template and functor.
It seems impossible to bring MethodOneImpl / MethodTwoImpl into the scope of Interface without having them inherit from Interface because they will not fill the Virtual Table if they don't. C++ misses something like the keyword implements from other languages.
So you are stuck with the virtual inheritence thing unless realize/accept that what you are looking for is just a bridge pattern, which does not satisfy requirement a) (you shall write more code), midly b) (code not necessarly difficult to maintain) and may satisfy c).
Here (another) possible solution (with only method though to reduce bloat)
class Interface
{ public:
virtual void method1() {return impl_->method1();}
private:
Interface() {}
protected:
struct Impl {
virtual void method1() = 0; };
std::shared_ptr<Impl> impl_;
Interface(const std::shared_ptr<Impl> &impl) : impl_(impl) {}
};
class InterfaceImpl : public Interface
{
struct Impl : public Interface::Impl {
void method1() { std::cout << "InterfaceImpl::method1() " << std::endl; } } ;
public:
InterfaceImpl() : Interface(std::shared_ptr<Impl> (new Impl)) {}
};
template <class T>
class GenericInterfaceImpl : public Interface {
struct Impl : public Interface::Impl {
Impl( T &t) : t_(t) {}
void method1() { t_.method1() ; }
T t_; };
public:
GenericInterfaceImpl() : Interface(std::shared_ptr<Impl> (new Impl(T()))) {}
};
struct AMethod1Impl {
void method1() { std::cout << "AMethod1Impl::method1() " << std::endl; } } ;
struct AnotherMethod1Impl_not_working {
void method1_not_present() { std::cout << "AnotherMethod1Impl_not_working ::method1_not_present() " << std::endl; } } ;
int main() {
// compilation of next line would fail
// (lame attempt to simulate ompilation fail when pure function not implemented)
// Interface inf;
std::unique_ptr<Interface> inf;
inf.reset(new InterfaceImpl);
inf->method1();
inf.reset(new GenericInterfaceImpl<AMethod1Impl>() );
inf->method1();
// compilation of next line would fail
// inf.reset(new GenericInterfaceImpl<AnotherMethod1Impl_not_working>() );
}
Does this serve your purpose?
It maintains the interface relationship and gives you maintainable code without having any consideration of client code.
Separating each method in functionoid and giving you the power to control the prototype of each method of the different base class.
#include <iostream>
#include <memory>
using namespace std;
//No Control over this.
class MethodOneImpl
{
private:
void method1(int x)
{ std::cout << "MethodOneImpl::method1() " << x << std::endl; }
public:
void method1() { method1(0); }
};
class MethodTwoImpl
{
public:
void myFunc(int x)
{ std::cout << "MethodTwoImpl::myFunc(x)" << x << std::endl; }
};
//*************************//
class Interface
{
public:
virtual void method1() = 0;
virtual void method2(int x) = 0;
};
//This is what i would do. //
class BaseFuncType
{
//no pure virtual
void Call()
{
throw "error";
}
void Call(int x)
{
throw "error";
}
};
class Method1: public BaseFuncType
{
auto_ptr<MethodOneImpl> MethodPtr;
public:
Method1()
{
MethodPtr.reset(new MethodOneImpl());
}
virtual int Call()
{
MethodPtr->method1();
}
};
class Method2: public BaseFuncType
{
auto_ptr<MethodTwoImpl> MethodPtr;
public:
Method2()
{
MethodPtr.reset(new MethodTwoImpl());
}
virtual int Call(int x)
{
MethodPtr->myFunc(x);
}
};
template <class T1>
class MethodFactory
{
private:
T1 methodObj;
public:
void CallMethod()
{
methodObj.Call();
}
void CallMethod(int x)
{
methodObj.Call(x);
}
};
class InterfaceImpl : public Interface
{
auto_ptr<MethodFactory> factory;
public:
virtual void method1()
{
factory.reset(new MethodFactory<Method1>());
factory->CallMethod();
}
virtual void method2(int x)
{
factory.reset(new MethodFactory<Method2>());
factory->CallMethod(x);
}
};
int main()
{
auto_ptr<Interface> inf;
inf.reset(new InterfaceImpl);
inf->method1();
inf->method2(10);
// This should be disallowed!
// std::unique_ptr<MethodOneImpl> moi;
// moi.reset(new InterfaceImpl);
}
I'm having a very odd problem that I'm hoping someone has come across.
class Letter
{
public:
Letter()
virtual ~Letter()
virtual std::string get() const = 0;
};
class A : public Letter
{
public:
A()
~A()
virtual std::string get() const { return "A"; }
};
class Board
{
public:
Board(){}
~Board()
{
std::cout << "Removing: " << letter->get() << std::endl;
delete letter;
}
void setLetter(Letter * l) { letter = l }
private:
Letter * letter;
}
int main()
{
Board b;
b.setLetter(new A());
}
The program causes a seg fault when Board goes out of scope at the line where the virtual function letter->get() is called in the destructor. I'm using gcc 4.1.2. Any ideas?
UPDATE
Okay, it seems what's actually happening in the real code is the equivalent of this:
class Board
{
public:
Board(){}
~Board()
{
std::cout << "Removing: " << letter->get() << std::endl;
}
void setLetter(Letter * l) { letter = l; }
private:
Letter* letter;
};
int main()
{
Board b;
A a;
b.setLetter(&a);
return 0;
}
In which case A is already out of scope when the virtual function is called.
I can only guess you're attempting to cast the std::string returned from get() to a char*. Otherwise i see no reason for the crash.
#include <iostream>
#include <string>
using namespace std;
class Letter
{
public:
Letter() {}
virtual ~Letter() {}
virtual std::string get() const = 0;
};
class A : public Letter
{
public:
A() {}
~A() {}
virtual std::string get() const { return "A"; }
};
class Board
{
public:
Board(){}
~Board()
{
std::cout << "Removing: " << letter->get() << std::endl;
delete letter;
}
void setLetter(Letter * l) { letter = l; }
private:
Letter * letter;
};
int main()
{
Board b;
b.setLetter(new A());
return 0;
}
no problem in gcc 4.5.2
I didn't realize an object was being passed to setLetter() from the stack, so A was going out of scope before b.
Board b;
A a;
b.setLetter(&a);
Some compilers doesn't allow Plain C / C++ constructors or destructors call virtual methods, seems like the (ANSI) C++ specification neither. And its not recommended.
Sometimes that requirement is useful. Some languages like Object Pascal explicit allow virtual methods calls within constructors and destructors.
One thing you can do its use the "Fake Virtual Constructor Pattern":
class MyClass
{
public:
// constructor
MyClass
{
// anything but virtual methods
}
// destructor
~MyClass
{
// anything but virtual methods
}
virtual void MyFakeConstructor()
{
MyVirtualMethod();
}
virtual void MyFakeDestructor()
{
MyVirtualMethod();
}
virtual void MyVirtualMethod()
{
// more stuff
}
// more members
}
int main(char[][] Args)
{
MyClass MyObject = new MyClass();
MyObject->MyFakeConstructor(); // <-- calls "MyVirtualMethod()"
MyObject->DoSomething1();
MyObject->DoSomething2();
MyObject->DoSomething3();
MyObject->MyFakeDestructor(); // <-- calls "MyVirtualMethod()"
delete MyObject;
return 0;
} // int main()
Another solution its that you arrange your code so you explicit call your virtual method outside the destructor.
Cheers.
Please see the example code below:
class A
{
private:
class B
{
public:
foobar();
};
public:
foo();
bar();
};
Within class A & B implementation:
A::foo()
{
//do something
}
A::bar()
{
//some code
foo();
//more code
}
A::B::foobar()
{
//some code
foo(); //<<compiler doesn't like this
}
The compiler flags the call to foo() within the method foobar(). Earlier, I had foo() as private member function of class A but changed to public assuming that B's function can't see it. Of course, it didn't help. I am trying to re-use the functionality provided by A's method. Why doesn't the compiler allow this function call? As I see it, they are part of same enclosing class (A). I thought the accessibility issue for nested class meebers for enclosing class in C++ standards was resolved.
How can I achieve what I am trying to do without re-writing the same method (foo()) for B, which keeping B nested within A?
I am using VC++ compiler ver-9 (Visual Studio 2008). Thank you for your help.
foo() is a non-static member function of A and you are trying to call it without an instance.
The nested class B is a seperate class that only has some access privileges and doesn't have any special knowledge about existing instances of A.
If B needs access to an A you have to give it a reference to it, e.g.:
class A {
class B {
A& parent_;
public:
B(A& parent) : parent_(parent) {}
void foobar() { parent_.foo(); }
};
B b_;
public:
A() : b_(*this) {}
};
This is an automagic, albeit possibly nonportable trick (worked on VC++ since 6.0 though). Class B has to be a member of class A for this to work.
#ifndef OUTERCLASS
#define OUTERCLASS(className, memberName) \
reinterpret_cast<className*>(reinterpret_cast<unsigned char*>(this) - offsetof(className, memberName))
#endif
class A
{
private:
class B
{
public:
void foobar() {
A* pA = OUTERCLASS(A, m_classB);
pA->foo();
}
} m_classB;
public:
foo();
bar();
};
Basically what Georg Fritzsche said
#include <iostream>
#include <cstring>
using namespace std;
class A
{
private:
class B
{
A& parent_;
public:
//B(); //uncommenting gives error
~B();
B(A& parent) : parent_(parent) {}
void foobar()
{
parent_.foo();
cout << "A::B::foo()" <<endl;
}
const std::string& foobarstring(const std::string& test) const
{
parent_.foostring(test); cout << "A::B::foostring()" <<endl;
}
};
public:
void foo();
void bar();
const std::string& foostring(const std::string& test) const;
A();
~A(){};
B b_;
};
//A::B::B() {}; //uncommenting gives error
A::B::~B(){};
A::A():b_(*this) {}
void A::foo()
{
cout << "A::foo()" <<endl;
}
const std::string& A::foostring(const std::string& test) const
{
cout << test <<endl;
return test;
}
void A::bar()
{
//some code
cout << "A::bar()" <<endl;
foo();
//more code
}
int main(int argc, char* argv[])
{
A a;
a.b_.foobar();
a.b_.foobarstring("hello");
return 0;
}
If you uncomment the default B constructor you would get an error
If you want to reuse functionality from A then you should inherit from A not nest B inside it.
Combining Igor Zevaka's and enthusiasticgeek's answers. Also, using reinterpret_cast for calculating offset (If you create class member variable using new keyword):
#include <iostream>
#include <cstring>
using namespace std;
template < typename T, typename U > constexpr size_t offsetOf(U T:: *member)
{
return (char*) &((T*) nullptr->*member) - (char*) nullptr;
}
class A
{
private:
class B
{
public:
B(string message);
~B();
void foobar()
{
A *pA = reinterpret_cast<A*> (reinterpret_cast< unsigned char*> (this) - offsetOf(&A::b_));
pA->foo();
pA->bar();
std::cout << "DONE!";
}
};
public:
void foo();
void bar();
A();
~A() {};
B* b_ = new B("Hello World!");
};
A::A()
{
cout << "A constructor\n";
};
A::B::B(string message) {
cout << "B constructor\n";
cout << "Message = " << message << "\n";
};
A::B::~B() {};
void A::foo()
{
cout << "A::foo()" << endl;
}
void A::bar()
{
cout << "A::bar()" << endl;
foo();
}
int main(int argc, char *argv[])
{
A* a = new A();
a->b_->foobar();
return 0;
}
Output:
B constructor
Message = Hello World!
A constructor
A::foo()
A::bar()
A::foo()
DONE!
References:
https://stackoverflow.com/a/10607424/9524565
https://stackoverflow.com/a/3058382/9524565
https://stackoverflow.com/a/20141143/9524565