class Base
{
protected:
template<typename TFunc>
void m_vProcess(TFunc& func) const
{
BasePrivateClass<TFunc> baseprivateobj(func);
// rest of code
}
private:
template<typename TFunc>
class BasePrivateClass
{
public:
BasePrivateClass(TFunc& obj) :m_obj(oParam)
{}
private:
TFunc& m_obj;
};
};
and this is my derived class:
class Derived: public Base
{
private:
class DerivedPrivateClass
{
public:
explicit DerivedPrivateClass(int **p): m_objDerived(poParam)
{}
private:
int** m_objDerived;
};
};
From a function in class Derived, I try this:
DerivedPrivateClass obj(param);
this->m_vProcess(obj);
I get a linker error of multiply defined symbols - symbols are defined in both base and derived class.
I have no idea what causes the linker error. Can anyone help?
As I commented.. a bit hard to read.. but from the looks of it, a main issue would be that the m_vProcessAnimParams function you are trying to use is private in Base, so Dervied cannot access it..
Related
I have a templated SafeSingleton class, Base class which is derived from SafeSingleton and implements some base methods. I want to have class that is derived from Base and can be accessed via instance() method of SafeSingleton. The problem is that when I am trying to access Derived::instance() it returns the pointer to a Base class and the compiler doesn't know anything about methods of derived class. What should I do to make below code work.
template<class T>
class SingleTon {
public:
static T* instance()
{
return holder().instance;
}
protected:
template<class I>
struct Holder
{
Holder() : instance(new I())
{
}
I* instance;
};
static Holder<T> &holder()
{
static Holder<T> holder;
return holder;
}
};
// Hopefully issue is here, I am never creating SingleTon<Derived>, but how can it be done?
class Base : public SingleTon<Base> {
public:
Base() = default;
void printBase() {
std::cout << "Base";
}
};
class Derived : public Base {
public:
Derived() = default;
void printDerived() {
std::cout << "Derived";
}
};
int main()
{
Derived::instance()->printBase();
Derived::instance()->printDerived(); // Here is the error
//Error: main.cpp:57:26: error: ‘class Base’ has no member named ‘printDerived’
//57 | Derived::instance()->printDerived();
return 0;
}
template<class D>
class Base : public SingleTon<D> {
and
class Derived : public Base <Derived>
and ... done?
If you want to put Base's non-Ddependent methods in a cpp file, you'll have to get fancy. Have BaseImp that does not derive from SingleTon, put code there. Have Base<D> derive from it and write forwarding glue to it BaseImpl. But you probably don't need this.
I'm trying to override an inherited function from a base class which is also a class template, but I can't get it to work.
Up to now the base class is:
template<typename T, typename instrument>
class Probe {
private:
instrument probe;
public:
Probe(instrument _probe) : probe{_probe} {}
virtual T read() const;
instrument getProbe() const {return this->probe;}
};
While the derived class is:
class TestProbe : public Probe<int,int> {
public:
TestProbe(int _probe) : Probe(_probe) {}
virtual int read() const override {return getProbe();} // later will have a more complex expression
};
The error I get whenever I try to compile is: undefined reference to Probe<int, int>::read() const
Assume I have a class, which stores references to the derived class member variables via a proxy class in a map. This map is populated in a function called let say foo(). It could look something like this:
#include <map>
#include <memory>
class property_base
{
};
template<typename T>
class property : public property_base
{
public:
property(T& property) : property_(property)
{
}
private:
T& property_;
};
template<typename T>
class base
{
public:
base()
{
static_cast<T*>(this)->foo();
}
protected:
std::map<std::string, std::unique_ptr<property_base>> properties_;
};
class derived : public base<derived>
{
public:
void foo()
{
properties_.emplace("member", std::unique_ptr<property_base>(new property<int>(value_)));
}
private:
int value_;
};
I know this is not considered a good pattern since I'm doing a bad thing - accessing the derived class member variables before their constructors have been run, but I only store the reference, so as far as I do not mess this up and start doing anything else with them this should be fine. That said, are there any cases/scenarios which I have overlooked and in which calling foo() which ONLY stores the references in the map would cause any errors?
I have a template class for which I need to access a protected member function of the template parameter, like this:
class Foo
{
protected:
void foo() {}
};
template<typename T>
class Bar
{
public:
static void bar(T& self){self.foo();}
};
...
Foo f;
Bar<Foo>::bar(f);
My problem is getting access to the protected method. I tried putting a friend class T into Bar, but that doesn't seem to be allowed in c++ (edit: and wouldn't solve my problem anyways, so it seemd). I tried letting Bar inherit from T (template<typename T> class Bar: public T (could have used private inheritance, but the public interface of Bar is not terribly important, since the class itself is internal only)), but that didn't allow for access of foo() either. So how do I get access to the foo() method?
Edit:
Foo should not need to know Bar<Foo>, since there are quite a lot Bar classes. I can however make other changes to Foo (without changing the public interface of course).
OK, this is a "rot in hell" hack. You can abuse the fact that you can form pointers-to-members pointing to protected base members from a derived class.
class Foo
{
protected:
void foo() {}
};
// Helper template to bypass protected access control
// for a member function called foo, taking no parameters
// and returning void.
template<typename T>
struct Unprotect : public T
{
typedef void (T::*FooPtr)();
static FooPtr GetFooPtr()
{
return &Unprotect::foo;
}
};
template<typename T>
class Bar
{
public:
static void bar(T& self){(self.*Unprotect<Foo>::GetFooPtr())();}
};
int main()
{
Foo f;
Bar<Foo>::bar(f);
}
You did your friend declaration in the wrong direction. If Bar says Foo is it's friend, that means Foo gets access to Bar's private data. For Bar to get access to Foo's private data, Foo has to say Bar is its friend.
template<typename T>
class Bar
{
public:
static void bar(T& self){self.foo();}
};
class Foo
{
protected:
void foo() {}
friend class Bar<Foo>;
};
void main()
{
Foo f;
Bar<Foo>::bar(f);
}
If you want to access a protected member a derived class of this, you can do it with the using keyword:
class A
{
protected:
void i_am_protected () {}
};
template <class T>
class B : public T
{
using T::i_am_protected;
void call_me ()
{
i_am_protected(); // OK.
this->i_am_protected(); // This compiles without the keyword.
}
};
If you need B to access a protected member of A when an object is passed to B, you need to declare B as a friend of A:
class A
{
template <class T>
friend
class B;
protected:
void i_am_protected () {}
};
template <class T>
class B : public T
{
void call_me (T& obj)
{
obj.i_am_protected(); // OK.
}
};
With c++, Is there a way to get a derived class to inherit its own static initializer? I am trying to do something like the following:
class Base {
public:
class StaticInit {
public:
virtual StaticInit() =0;
};
};
class Derived: public Base {
public:
virtual StaticInit::StaticInit() {
//do something with the derived class
}
static StaticInit init;
}
static Derived::StaticInit init;
it would also be nice if I didn't have to define the init var in each derived class. I am currently redefining the StaticInit internal class in each derived class but it seems redundant.
Each derived class is a singleton, and I need the instance to be stored in a lookup table at program startup.
I use templates to do this, rather than inheritance - something like:
template <typename T>
struct StaticInit {
StaticInit() {
// do whatever with T
}
};
in use:
static StaticInit <SomeClass> init;
Use the CRTP:
template <class D>
class Base {
public:
class StaticInit {
public:
StaticInit() { D::initStatic(*this); }
};
static StaticInit init;
};
template <class D>
Base<D>::StaticInit init;
class Derived: public Base<Derived> {
public:
initStatic(Base<Derived>::StaticInit& s) {
// Do derived-specific initialisation on s.
}
}