Reputation: 2074
I have an object S
. S
is composed of layers S0
, S1
, S2
... just like a stack of stackable drawers.
I want to create a chain of template classes A
, B
, C
such that:
S
object. C
can convert to B
, which can convert to A
.A
, B
, and C
have different sets of methods.The problem is that if I use public inheritance, then C
will get the methods of A
and B
.
Test:
#include <iostream>
// Library
template <typename T>
class A {
public:
void a() {std::cout << "a\n"; }
int s_{0};
};
template <typename T>
class B : public A<T> {
public:
void b() {std::cout << "b\n"; }
};
template <typename T>
class C : public B<T> {
public:
void c() {std::cout << "c\n"; }
};
// User of library write a function like this
template <typename T>
void foo(A<T>& a) { a.a(); }
// The problem:
int main() {
C<int> c;
foo(c);
c.a(); // <--- how to hide this?
return 0;
}
Upvotes: 1
Views: 57
Reputation: 1863
I'm not sure if I understand what you want. But one way to do it is changing the access level of base class member in derived class. For example:
template <typename T>
class C : public B<T> {
public:
void c() { std::cout << "c\n"; }
private:
using A::a; // <-- reduce access level of base class member
};
Upvotes: 1
Reputation: 2074
"Just" need 0 + 1 + 2 + ... + i conversion operators for layer Si
Or one template conversion operator if their attributes are all the same.
But this still need some way to control the conversions.
#include <iostream>
template <typename T>
class A {
public:
A(int& layer) : layer_(layer) {}
void a() {std::cout << "a\n"; }
int s_{0};
private:
int& layer_;
};
template <typename T>
class B {
public:
B(int& layer) : a_(layer) { }
template <template<typename> class X, typename T2>
operator X<T2>() { return a_; }
void b() {std::cout << "b\n"; }
private:
A<T> a_;
};
template <typename T>
class C {
public:
C(int& layer) : b_(layer) {}
template <template<typename> class X, typename T2>
operator X<T2>() { return b_; }
void c() {std::cout << "c\n"; }
private:
B<T> b_;
};
template <typename T>
class D {
public:
D(int& layer) : c_(layer) {}
template <template<typename> class X, typename T2>
operator X<T2>() { return c_; }
void c() {std::cout << "c\n"; }
private:
C<T> c_;
};
template <template<typename> class X, typename T>
void foo(X<T>& a) {
A<T>(a).a();
}
int main() {
int v = 1;
D<int> d(v);
foo(d);
return 0;
}
Upvotes: 0