C++ multiple inheritance static function call ambiguity - c++

I have the case where I am deriving a class from two different base classes both having a static function with the same name.
To resolve this ambiguity, I tried to use the scope operator - just as I would do for a member function. However This does not compile. Why? Wrong syntax?
I want to call the static function via the derived typename and not directly via base class name. Actually I would like prefer to prevent this case, but I have no idea how to do so.
The error (commented out) in the code below also occurs, when I leave the templates away:
#include <iostream>
template<class TDerived>
class StaticBaseA
{
public:
static void announce()
{
std::cout << "do something" << std::endl;
}
};
template<class TDerived>
class StaticBaseB
{
public:
static void announce()
{
std::cout << "do something else" << std::endl;
}
};
class Derived :
public StaticBaseA<Derived>
, public StaticBaseB<Derived>
{
using StaticBaseA<Derived>::announce;
};
class NonDerived {};
int main(int argc, char* argv[])
{
Derived::announce();
// What I want:
//Derived::StaticBaseB<Derived>::announce(); Error: "Undefined symbol 'StaticBaseB'
// What works, but what I don't want ...
StaticBaseB<Derived>::announce();
// ... because I would like to prevent this (however this is done):
StaticBaseB<NonDerived>::announce();
return 0;
}

Making "announce" protected in StaticBaseA and StaticBaseB might be part-way to doing what you want.
You then could not call StaticBaseB<NonDerived>::announce from main as it would be inaccessible. You could call it from a class derived from StaticBaseB.
In other words:
template<class TDerived>
class StaticBaseA
{
protected:
static void announce()
{
std::cout << "do something" << std::endl;
}
};
template<class TDerived>
class StaticBaseB
{
protected:
static void announce()
{
std::cout << "do something else" << std::endl;
}
};
In Derived you have to promote "announce" to public.
class Derived : public StaticA<Derived>, public StaticB<Derived >
{
public:
using StaticA<Derived>::announce;
};
int main()
{
Derived::announce(); // legal and calls StaticBaseA::announce
NotDerived::announce(); // no such function
StaticBaseA< Derived >::announce(); // not accessible
StaticBaseB< Derived >::announce(); // also not accessible
StaticBaseA< NotDerived >::announce(); // not accessible
StaticBaseB< NotDerived >::announce(); // also not accessible
}

Related

Is there a design pattern like this? [duplicate]

I'll start by explaining my situation.
I have a base class that automatically implements a type of reference counting. It allows me to wrap C-style init() and free() library calls into a reference-counted API.
template<typename T>
class Service {
public:
Service() {
if(s_count++ == 0) {
T::initialize();
}
}
~Service() {
if(--s_count == 0) {
T::terminate();
}
}
private:
static int s_count;
};
template<typename T>
int Service<T>::s_count = 0;
Classes that wish to implement these initializers and terminators will derive from Service like so:
class Test : public Service<Test> {
friend class Service<Test>;
private:
static void initialize() {
std::cout << "Initialized" << std::endl;
}
static void terminate() {
std::cout << "Terminated" << std::endl;
}
};
However, the declaration is messy since I have to both inherit from and friend my Service class. Is there any way to allow a base class access to protected or private members of a derived class automatically? If not, I may as well ask if there's any better way to write what I've done here.
"Is there any way to allow a base class access to protected or private members of a derived class automatically?"
Base class cannot access private/protected members of derived class formally. In general base classes are designed such a way that they don't need to know anything of derived class. So, if there is a need to access members in derived class from your base class then you should re-consider your design.
EDIT ( As per proposed article by #RSahu ):-
Although there are some scenario where it might be useful to access member functions of derived class from base class. Like when you are sharing objects between two processes.
#include <iostream>
using namespace std;
template<typename T>
class Service {
struct TT: T {
using T::initialize;
using T::terminate;
};
public:
Service() {
if(s_count++ == 0) {
TT::initialize();
}
}
~Service() {
if(--s_count == 0) {
TT::terminate();
}
}
private:
static int s_count;
};
class Test : public Service<Test> {
//friend class Service<Test>;
protected:
static void initialize() {
std::cout << "Initialized" << std::endl;
}
static void terminate() {
std::cout << "Terminated" << std::endl;
}
};
template<typename T>
int Service<T>::s_count = 0;
int main() {
Test t;
}
n.m.'s suggestion of making these methods virtual made me think: it would not work by itself, but it would work if you decouple the service from its management: the initialization doesn't just applies to that particular service instance, it applies to all instances, and perhaps because of that it just shouldn't be part of the service class in the first place.
If you decouple them, you can make a service manager base class, with virtual methods that a derived service manager must implement, like so:
#include <iostream>
class ServiceManager {
template <typename T>
friend class Service;
virtual void initialize() = 0;
virtual void terminate() = 0;
};
template <typename T>
class Service {
public:
Service() {
if (s_count++ == 0) {
s_manager.initialize();
}
}
~Service() {
if (--s_count == 0) {
s_manager.terminate();
}
}
private:
static int s_count;
static ServiceManager &&s_manager;
};
template <typename T>
int Service<T>::s_count = 0;
template <typename T>
ServiceManager &&Service<T>::s_manager = T();
class TestManager : public ServiceManager {
void initialize() {
std::cout << "Initialized" << std::endl;
}
void terminate() {
std::cout << "Terminated" << std::endl;
}
};
class Test : public Service<TestManager> {
};
If your compiler doesn't support this use of && (it's valid C++11, but not valid C++03), you should still be able to easily adapt the code by either making s_manager ServiceManager & and not using a temporary T to initialise it, or just making s_manager have type T. The former is more verbose, the latter allows T implementations that do not derive from ServiceManager.

C++ calling a inherited method of a templated superclass

I don't understand why the following code does not compile:
#include <iostream>
using namespace std;
template<typename T>
class Base {
public:
void printTuple(T tuple) {
std::cout << "Hello1!" << std::endl;
}
};
template<typename T>
class Derived : public Base<T> {
public:
void printTuple(std::string name, T tuple) {
std::cout << "Hello2!" << std::endl;
printTuple(tuple);
}
};
int main()
{
Derived<int> d1;
d1.printTuple("Test", 13);
return 0;
}
I get the following error:
main.cpp:19:25: error: no matching function for call to Derived::printTuple(int&)'
But shouldn't Derived inherit a method with such a signature from Base?
Thanks
You should change the line printTuple(tuple) to Base<T>::printTuple(tuple) because a function of the base class has been hidden.
Just add this to the top of the public part of class Derived:
using Base<T>::printTuple;
This will expose the base class overload of the function, i.e. prevent it from being "shadowed."

Give protected access to base class without friend

I'll start by explaining my situation.
I have a base class that automatically implements a type of reference counting. It allows me to wrap C-style init() and free() library calls into a reference-counted API.
template<typename T>
class Service {
public:
Service() {
if(s_count++ == 0) {
T::initialize();
}
}
~Service() {
if(--s_count == 0) {
T::terminate();
}
}
private:
static int s_count;
};
template<typename T>
int Service<T>::s_count = 0;
Classes that wish to implement these initializers and terminators will derive from Service like so:
class Test : public Service<Test> {
friend class Service<Test>;
private:
static void initialize() {
std::cout << "Initialized" << std::endl;
}
static void terminate() {
std::cout << "Terminated" << std::endl;
}
};
However, the declaration is messy since I have to both inherit from and friend my Service class. Is there any way to allow a base class access to protected or private members of a derived class automatically? If not, I may as well ask if there's any better way to write what I've done here.
"Is there any way to allow a base class access to protected or private members of a derived class automatically?"
Base class cannot access private/protected members of derived class formally. In general base classes are designed such a way that they don't need to know anything of derived class. So, if there is a need to access members in derived class from your base class then you should re-consider your design.
EDIT ( As per proposed article by #RSahu ):-
Although there are some scenario where it might be useful to access member functions of derived class from base class. Like when you are sharing objects between two processes.
#include <iostream>
using namespace std;
template<typename T>
class Service {
struct TT: T {
using T::initialize;
using T::terminate;
};
public:
Service() {
if(s_count++ == 0) {
TT::initialize();
}
}
~Service() {
if(--s_count == 0) {
TT::terminate();
}
}
private:
static int s_count;
};
class Test : public Service<Test> {
//friend class Service<Test>;
protected:
static void initialize() {
std::cout << "Initialized" << std::endl;
}
static void terminate() {
std::cout << "Terminated" << std::endl;
}
};
template<typename T>
int Service<T>::s_count = 0;
int main() {
Test t;
}
n.m.'s suggestion of making these methods virtual made me think: it would not work by itself, but it would work if you decouple the service from its management: the initialization doesn't just applies to that particular service instance, it applies to all instances, and perhaps because of that it just shouldn't be part of the service class in the first place.
If you decouple them, you can make a service manager base class, with virtual methods that a derived service manager must implement, like so:
#include <iostream>
class ServiceManager {
template <typename T>
friend class Service;
virtual void initialize() = 0;
virtual void terminate() = 0;
};
template <typename T>
class Service {
public:
Service() {
if (s_count++ == 0) {
s_manager.initialize();
}
}
~Service() {
if (--s_count == 0) {
s_manager.terminate();
}
}
private:
static int s_count;
static ServiceManager &&s_manager;
};
template <typename T>
int Service<T>::s_count = 0;
template <typename T>
ServiceManager &&Service<T>::s_manager = T();
class TestManager : public ServiceManager {
void initialize() {
std::cout << "Initialized" << std::endl;
}
void terminate() {
std::cout << "Terminated" << std::endl;
}
};
class Test : public Service<TestManager> {
};
If your compiler doesn't support this use of && (it's valid C++11, but not valid C++03), you should still be able to easily adapt the code by either making s_manager ServiceManager & and not using a temporary T to initialise it, or just making s_manager have type T. The former is more verbose, the latter allows T implementations that do not derive from ServiceManager.

CRTP compiles, but I'd like it not to. How?

I have this CRTP with an incomplete child class that is missing a method that is "not really" implemented in the base class:
#include <iostream>
using namespace std;
template<class T>
class BaseA
{
public:
T& asChild(){return static_cast<T&>(*this);}
void AMethod(void) {asChild().AMethod();}
};
class IncompleteChild : public BaseA<IncompleteChild>
{
public:
// uncomment the following to avoid segfault:
// void AMethod(void) {cout << "IncompleteChild Method" << endl;}
};
class Child : public BaseA<Child>
{
public:
void AMethod(void) {cout << "Child AMethod" << endl;}
};
template<class T>
void printBaseA(BaseA<T>& a)
{
a.AMethod();
}
int main()
{
IncompleteChild cI;
cI.AMethod();
printBaseA(cI);
return 0;
}
This compiles fine, but results in a segmentation fault at runtime. How can I avoid that? I'd prefer a compiler error here (using gcc 4.6.3).
Since your class doesn't actually have a member AMethod, you end up calling the member of the CRTP base, which gives you infinite recursion.
The simple solution is not to reuse names all over the place, but have one called AMethod and the other AMethodImpl or something like that:
void AMethod()
{
static_cast<T*>(this)->AMethodImpl();
}

C++: Require static function in abstract class

I am trying to write a c++ abstract class and I can't figure out how to require implementers of this class to contain a static function.
For example:
class AbstractCoolThingDoer
{
void dosomethingcool() = 0; // now if you implement this class
// you better do this
}
class CoolThingDoerUsingAlgorithmA: public AbstractCoolthingDoer
{
void dosomethingcool()
{
//do something cool using Algorithm A
}
}
class CoolThingDoerUsingAlgorithmB: public AbstractCoolthingDoer
{
void dosomethingcool()
{
//do the same thing using Algorithm B
}
}
Now I'd like to do the coolthing without the details of how coolthing gets done. So I'd like to do something like
AbstractCoolThingDoer:dosomethingcool();
without needing to know how the coolthing gets done, but this seems to require a function that is both virtual and static which is of course a contradiction.
The rationale is that CoolThingDoerUsingAlgorithmB may be written later and hopefully the softare that needs cool things done won't have to be rewritten.
EDIT:Not sure I was clear on what I'm trying to accomplish. I have 3 criteria that I'm looking to satisfy
A library that uses abstractcoolthingdoer and does not need to be rewritten ever, even when another coolthingdoer is written that the library has never heard of.
If you try to write a coolthingdoer that doesn't conform to the required structure, then the executable that uses the library won't compile.
coolthingdoer has some static functions that are required.
I'm probably chasing down a poor design, so please point me to a better one. Am I needing a factory?
Maybe, something like this will help (see ideone.com example):
#include <iostream>
class A
{
protected:
virtual void do_thing_impl() = 0;
public:
virtual ~A(){}
static void do_thing(A * _ptr){ _ptr->do_thing_impl(); }
};
class B : public A
{
protected:
void do_thing_impl(){ std::cout << "B impl" << std::endl; }
};
class C : public A
{
protected:
void do_thing_impl(){ std::cout << "C impl" << std::endl; }
};
int main()
{
B b_;
C c_;
A::do_thing(&b_);
A::do_thing(&c_);
return (0);
}
EDIT: It seems to me the OP does not need run-time polymorphism, but rather compile-time polymorphism without need of class instance (use of static functions when the implementation is hidden in the derived classes, no instance required). Hope the code below helps to solve it (example on ideone.com):
#include <iostream>
template <typename Derived>
struct A
{
static void do_thing() { Derived::do_thing(); }
};
struct B : public A<B>
{
friend A<B>;
protected:
static void do_thing() { std::cout << "B impl" << std::endl; }
};
struct C : public A<C>
{
friend A<C>;
protected:
static void do_thing() { std::cout << "C impl" << std::endl; }
};
int main()
{
A<B>::do_thing();
A<C>::do_thing();
return (0);
}
EDIT #2: To force fail at compile-time in case user does not adhere to desired pattern, here is the slight modification at ideone.com:
#include <iostream>
template <typename Derived>
struct A
{
static void do_thing() { Derived::do_thing_impl(); }
};
struct B : public A<B>
{
friend A<B>;
protected:
static void do_thing_impl() { std::cout << "B impl" << std::endl; }
};
struct C : public A<C>
{
friend A<C>;
protected:
static void do_thing_impl() { std::cout << "C impl" << std::endl; }
};
struct D : public A<D>
{
friend A<D>;
};
int main()
{
A<B>::do_thing();
A<C>::do_thing();
A<D>::do_thing(); // This will not compile.
return (0);
}
This looks to me like right place to implement bridge pattern. Maybe this is what you are (unconsciously) willing to achieve. In short you specify an interface and its implementations, then call to your do_thing method in turn calls an implementation on a pointer to implementer class.
C++ example