I am working on a project that had been thought out, rather poorly. I have subclasses that access each other's member functions. Here's the situation:
class A {
public:
class B;
class C;
};
class A::B {
public:
void f() {
C:g();
}
}
class A::C {
public:
void g() {
B:f();
}
}
This code, obviously, runs into various errors which is too much list here. My question is, what is the solution to such a situation? Is it inheritance? If so, how? Is there any other way for me to preserve the "interplaying"-nature of classes B and C.
If you mean C:g() --> C::g(), B:f() --> B::f()
You can not call member function without object unless these member functions are static.
Probably a pointer to each other may resolve your issue?
I introduce pointer is because otherwise I need to write something to help with circular include issue. :)
#include <memory>
class A::B {
public:
void f() {
c_->g();
}
std::unique_ptr<C> c_;
}
class A::C {
public:
void g() {
b_->f();
}
std::unique_ptr<B> b_;
}
move method definitions out of class declarations, so both classes will be declared and their methods are visible to each other
Related
It is very easy that we can make sure derived class must implement interface defined in base class.
That is pure virtual function.
For example:
class BaseClass
{
...
virtual void print()=0;
...
}
class DerivedClass :public BaseClass
{
// function must be implement, otherwise compiler will complain ...
void print()
{
}
};
Can we defined a static interface in base class and make sure the interface must be implement in derivate class?
I want something like this
class BaseClass
{
...
static void print(); // base class only define static interface
...
}
class DerivedClass :public BaseClass
{
// derived class must implement interface, otherwise compiler will complain ...
static void print()
{
}
};
I have no idea about this.
Thanks for your time.
It is not possible to make a virtual static function. For the simple reason that when calling a static function, you always know the class that defines that function in compile time. Unlike virtual functions, where you don't know the type of the object whose method you're calling.
For example:
class A
{
public:
virtual void f() {printf("A");}
};
class B : public A
{
virtual void f() override {printf("B");}
};
void g(A& a)
{
a.f();
}
int main()
{
B b;
g(b);
return 0;
}
In the above example, inside the function g, the correct function is invoked (B::f). Even though while compiling the function it is not known what the type of its argument is (it could be A or any class derived from A).
Without making f() virtual, you would have overloaded the method f, rather than overridden it. Which means that in the following example, the output would be "A", even though you might expect it to be "B":
class A
{
public:
void f() {printf("A");}
};
class B : public A
{
void f() {printf("B");}
};
void g(A& a)
{
a.f();
}
int main()
{
B b;
g(b);
return 0;
}
This may cause serious bugs, and it is suggested to never overload base class methods, and to always use the override keyword when overriding a virtual method to escape those bugs.
When making a static function, you can simply overload it, it would not create a compilation error. However, you probably never should overload it, because it may hide a bug that is very difficult to track (you are certain that B::f() is being called while actually A::f() is being called).
Furthermore, it is not possible to 'force' the derived class to implement a static interface, because there is no such thing as a static interface. Because you have no virtual static functions, you may not pass a reference or pointer to the interface that would implement this function.
class A {
public:
void fa() {
}
};
class B : public A{
public:
void fb() {
}
};
class C : public A, public B {
public:
void fc() {
//call A::fa(), not B::A::fa();
}
};
How to call A::fa() from C::fc() function.
GCC warns withdirect base A inaccessible in C due to ambiguity, does this mean there is no direct way to refer base class members?
One option would be to create a stub class that you can use for casting to the right base class subobject:
struct A {
void fa() { }
};
struct B : A {
void fb() { }
};
// Use a stub class that we can cast through:
struct A_ : A { };
struct C : A_, B {
void fc() {
implicit_cast<A_&>(*this).fa();
}
};
Where implicit_cast is defined as:
template <typename T> struct identity { typedef T type; }
template <typename T>
T implicit_cast(typename identity<T>::type& x) { return x; }
I just found the following info from ISO C++ 2003 standard (10.1.3)
A class shall not be specified as a direct base class of a derived class more than once. [Note: a class can be
an indirect base class more than once and can be a direct and an indirect base class. There are limited
things that can be done with such a class. The non-static data members and member functions of the direct
base class cannot be referred to in the scope of the derived class. However, the static members, enumerations
and types can be unambiguously referred to.
It means there is no direct way :(
I just compiled you code on codepad.org , putting A::fa() is enough to call fa() from your C::fc() function.
void fc() {
A::fa();
}
The below is the link to codepad with your code.
http://codepad.org/NMFTFRnt
I don't think you can do what you want. There is an ambiguity here: when you say A::fa(), it still doesn't tell the compiler which A object to use. There isn't any way to access class A. That's what the warning is telling you.
This seems like an awfully strange construct, though. Public inheritance should be used for is-a relationships. You are saying that C is-a A twice over? It doesn't make sense. And that suggests that this is either an artificial example that would never come up in practice, or you should reconsider this design.
You can use virtual inheritance to overcome such problem:
class B : virtual public A {
Now, you can use A::fa() simply in the child class C.
void fc()
{
fa();
}
However, I generally don't see any practical need to inherit class A again into class C, when B is already publically inheriting A. So, In your case, you can make it simple:
class C : public B {
Edit:
If you want 2 instances for A. then the direct instance which you are intending can be made as an object of C:
class C : public B {
A obj;
Because, having a directly inherited A will not be usable in anyway. You cannot declare any pointer or reference to it inside the scope of C.
for a certain project I have declared an interface (a class with only pure virtual functions) and want to offer users some implementations of this interface.
I want users to have great flexibility, so I offer partial implementations of this interface. In every implementation there is some functionality included, other functions are not overridden since they take care about different parts.
However, I also want to present users with a fully usable implementation of the interface as well. So my first approach was to simply derive a class from both partial implementations. This did not work and exited with the error that some functions are still pure virtual in the derived class.
So my question is if there is any way to simply merge two partial implementations of the same interface. I found a workaround by explicitely stating which function I want to be called for each method, but I consider this pretty ugly and would be grateful for an mechanism taking care of this for me.
#include <iostream>
class A{
public:
virtual void foo() = 0;
virtual void bar() = 0;
};
class B: public A{
public:
void foo(){ std::cout << "Foo from B" << std::endl; }
};
class C: public A{
public:
void bar(){ std::cout << "Bar from C" << std::endl; }
};
// Does not work
class D: public B, public C {};
// Does work, but is ugly
class D: public B, public C {
public:
void foo(){ B::foo(); }
void bar(){ C::bar(); }
};
int main(int argc, char** argv){
D d;
d.foo();
d.bar();
}
Regards,
Alexander
The actual problem is about managing several visitors for a tree, letting each of them traverse the tree, make a decision for each of the nodes and then aggregate each visitor's decision and accumulate it into a definite decision.
A separation of both parts is sadly not possible without (I think) massive overhead, since I want to provide one implementation taking care of managing the visitors and one taking care of how to store the final decision.
Have you considered avoiding the diamond inheritance completely, providing several abstract classes each with optional implementations, allowing the user to mix and match default implementation and interface as needed?
In your case what's happening is that once you inherit to D, B::bar hasn't been implemented and C::foo hasn't been implemented. The intermediate classes B and C aren't able to see each others' implementations.
If you need the full interface in the grandparent, have you considered providing the implementation in a different way, possibly a policy with templates, and default classes that will be dispatched into to provide the default behavior?
If your top level interface has a logical division in functionality, you should split it into two separate interfaces. For example if you have both serialization and drawing functions in interface A, you should separate these into two interfaces, ISerialization and IDrawing.
You're free to then provide a default implementation of each of these interfaces. The user of your classes can inherit either your interface or your default implementation as needed.
There is also the possibility that you could use a "factory" class for the main interface type. In other words the primary interface class also contains some type of static function that generates an appropriate child class on-request from the user. For instance:
#include <cstdio>
class A
{
public:
enum class_t { CLASS_B, CLASS_C };
static A* make_a_class(class_t type);
virtual void foo() = 0;
virtual void bar() = 0;
};
class B: public A
{
private:
virtual void foo() { /* does nothing */ }
public:
virtual void bar() { printf("Called B::bar()\n"); }
};
class C: public A
{
private:
virtual void bar() { /* does nothing */ }
public:
virtual void foo() { printf("Called C::foo()\n"); }
};
A* A::make_a_class(class_t type)
{
switch(type)
{
case CLASS_B: return new B();
case CLASS_C: return new C();
default: return NULL;
}
}
int main()
{
B* Class_B_Obj = static_cast<B*>(A::make_a_class(A::CLASS_B));
C* Class_C_Obj = static_cast<C*>(A::make_a_class(A::CLASS_C));
//Class_B_Obj->foo(); //can't access since it's private
Class_B_Obj->bar();
Class_C_Obj->foo();
//Class_C_Obj->bar(); //can't access since it's private
return 0;
}
If class A for some reason needs to access some private members of class B or class C, just make class A a friend of the children classes (for instance, you could make the constructors of class B and class C private constructors so that only the static function in class A can generate them, and the user can't make one on their own without calling the static factory function in class A).
Hope this helps,
Jason
Since you mentioned that you mainly needed access to the functions rather than data-members, here is another method you could use rather than multiple inheritance using templates and template partial specialization:
#include <iostream>
using namespace std;
enum class_t { CLASS_A, CLASS_B, CLASS_C };
template<class_t class_type>
class base_type
{
public:
static void foo() {}
static void bar() {}
};
template<>
void base_type<CLASS_A>::foo() { cout << "Calling CLASS_A type foo()" << endl; }
template<>
void base_type<CLASS_B>::bar() { cout << "Calling CLASS_B type bar()" << endl; }
template<>
void base_type<CLASS_C>::foo() { base_type<CLASS_A>::foo(); }
template<>
void base_type<CLASS_C>::bar() { base_type<CLASS_B>::bar(); }
int main()
{
base_type<CLASS_A> Class_A;
Class_A.foo();
base_type<CLASS_B> Class_B;
Class_B.bar();
base_type<CLASS_C> Class_C;
Class_C.foo();
Class_C.bar();
return 0;
}
Now if you need non-static functions that have access to private data-members, this can get a bit trickier, but it should still be doable. It would though most likely require the need for a separate traits class you can use to access the proper types without running into "incomplete types" compiler errors.
Thanks,
Jason
I think the problem is that when using simple inheritance between B and A, and between C and A, you end up with two objects of type A in D (each of which will have a pure virtual function, causing a compile error because D is thus abstract and you try to create an instance of it).
Using virtual inheritance solves the problem since it ensure there is only one copy of A in D.
This code:
class B {
protected:
void Foo(){}
}
class D : public B {
public:
void Baz() {
Foo();
}
void Bar() {
printf("%x\n", &B::Foo);
}
}
gives this error:
t.cpp: In member function 'void D::Bar()':
Line 3: error: 'void B::Foo()' is protected
Why can I call a protected method but not take its address?
Is there a way to mark something fully accessible from derived classes rather than only accessible from derived classes and in relation to said derived class?
BTW: This looks related but what I'm looking for a reference to where this is called out in the spec or the like (and hopefully that will lead to how to get things to work the way I was expecting).
You can take the address through D by writing &D::Foo, instead of &B::Foo.
See this compiles fine : http://www.ideone.com/22bM4
But this doesn't compile (your code) : http://www.ideone.com/OpxUy
Why can I call a protected method but not take its address?
You cannot take its address by writing &B::Foo because Foo is a protected member, you cannot access it from outside B, not even its address. But writing &D::Foo, you can, because Foo becomes a member of D through inheritance, and you can get its address, no matter whether its private, protected or public.
&B::Foo has same restriction as b.Foo() and pB->Foo() has, in the following code:
void Bar() {
B b;
b.Foo(); //error - cannot access protected member!
B *pB = this;
pB->Foo(); //error - cannot access protected member!
}
See error at ideone : http://www.ideone.com/P26JT
This is because an object of a derived class can only access protected members of a base class if it's the same object. Allowing you to take the pointer of a protected member function would make it impossible to maintain this restriction, as function pointers do not carry any of this information with them.
I believe protected doesn't work the way you think it does in C++. In C++ protected only allows access to parent members of its own instance NOT arbitrary instances of the parent class. As noted in other answers, taking the address of a parent function would violate this.
If you want access to arbitrary instances of a parent, you could have the parent class friend the child, or make the parent method public. There's no way to change the meaning of protected to do what you want it to do within a C++ program.
But what are you really trying to do here? Maybe we can solve that problem for you.
Why can I call a protected method but not take its address?
This question has an error. You cannot do a call either
B *self = this;
self->Foo(); // error either!
As another answer says if you access the non-static protected member by a D, then you can. Maybe you want to read this?
As a summary, read this issue report.
Your post doesn't answer "Why can I
call a protected method but not take
its address?"
class D : public B {
public:
void Baz() {
// this line
Foo();
// is shorthand for:
this->Foo();
}
void Bar() {
// this line isn't, it's taking the address of B::Foo
printf("%x\n", &B::Foo);
// not D:Foo, which would work
printf("%x\n", &D::Foo);
}
}
Is there a way to mark something fully accessible from derived classes rather than only accessible from derived classes and in relation to said derived class?
Yes, with the passkey idiom. :)
class derived_key
{
// Both private.
friend class derived;
derived_key() {}
};
class base
{
public:
void foo(derived_key) {}
};
class derived : public base
{
public:
void bar() { foo(derived_key()); }
};
Since only derived has access to the contructor of derived_key, only that class can call the foo method, even though it's public.
The obvious problem with that approach is the fact, that you need to friend every possible derived class, which is pretty error prone. Another possible (and imho better way in your case) is to friend the base class and expose a protected get_key method.
class base_key
{
friend class base;
base_key() {}
};
class base
{
public:
void foo(base_key) {}
protected:
base_key get_key() const { return base_key(); }
};
class derived1 : public base
{
public:
void bar() { foo(get_key()); }
};
class derived2 : public base
{
public:
void baz() { foo(get_key()); }
};
int main()
{
derived1 d1;
d1.bar(); // works
d1.foo(base_key()); // error: base_key ctor inaccessible
d1.foo(d1.get_key()); // error: get_key inaccessible
derived2 d2;
d2.baz(); // works again
}
See the full example on Ideone.
Standard reference: https://en.cppreference.com/w/cpp/language/access#Protected_member_access
When a pointer to a protected member is formed, it must use a derived class in its declaration:
struct Base {
protected:
int i;
};
struct Derived : Base {
void f() {
// int Base::* ptr = &Base::i; // error: must name using Derived
int Base::* ptr = &Derived::i; // OK
}
};
i have an inheritance struct A : public B, i want to hide individual functions from B, is this possible?
i know the opposite is possible using using BMethod in the A declaration.
cheers
If you want to selectively hide functions from B it does not make much sense to use public inheritance in the first place.
Use private inheritance & selectively bring methods from B into the scope of A:
struct B{
void method1(){};
void method2(){};
};
struct A : private B{
using B::method1;
};
A a;
a.method1();
a.method2(); //error method2 is not accesible
There is an issue here: this would be a direct violation of the Liskov Substitution Principle, namely A would not act as a B any longer.
If you wish to reuse B implementation, the solution is simply to do so:
class A
{
public:
void foo() { return b.foo(); }
void bar() { return b.bar(); }
// ...
private:
B b;
};
Don't abuse inheritance, use composition instead
The using keyword can be used to change visibility
struct A
{
void method1();
};
struct B: public A
{
void method2();
private:
using A::method1;
};
Aside from the ways described in the previous answers—composition, private inheritance, and non-private inheritance but with the inherited method declared private—another way is to explicitly delete the inherited method:
#include <iostream>
struct A {
void foo() { std::cout << "foo\n"; }
};
struct B : A {
void foo() = delete;
};
int main() {
B b;
b.foo(); // COMPILER ERROR
}
Although the b.foo() call produces a compiler error, client code can still call the base class’s version by qualifying with the base class identifier A:
b.A::foo(); // compiles, outputs 'foo' to console
This explicit deletion way works when foo is not a virtual non-deleted method in A. By C++11 Standard §10.3/16, this explicit deletion is ill-formed when the deleted method in the derived class overrides a virtual non-deleted method of the base class. For more info on this restriction, see the answers to the SO question C++11 Delete Overriden Method.
You can't "hide it" per se, but you can make it a compile time error to call it. Example:
struct A
{
void AMethod() {}
};
class B : public A
{
void AMethod() {} //Hides A::AMethod
};
int main()
{
B myB;
myB.AMethod(); //Error: AMethod is private
static_cast<A*>(&myB)->AMethod(); //Ok
return 0;
}
Examples on codepad with the error, and without.
That all said, despite this being possible, you really shouldn't do it. You'll confuse the hell out of clients.
EDIT: Note that you can also do this with virtual functions (And with the error).
To those that are suggesting composition... this might not be the best possible way of going about things. My understanding is that the Liskov Substitution Principle only states that there's the possibility of the functions from the base class being used on the child, not that they necessarily should be. For example, for a particular base class you may have multiple functions that essentially perform the same operation, but for different specific cases. In the derived class you may want to abstract these public functions away in favor of simplifying the user's interface. This is where private inheritance can be used. Private inheritance might also be a necessity, if we have protected functions in the base class that we don't want the user of the base class to call, yet would be invaluable to the derived class.
In short, if you HAVE to, use private inheritance, but composition is preferred in most cases.
There is yet another approach.
class A{
void f1();
void f2();
void f3();
}
class BInterface{
void f2();
void f3();
}
class B : public A, BInterface
{
}
BInterface b = new B();
b->f1(); //doesn't work since f1 is not declared in BInterface
b->f2(); //should work
b->f3(); //should work
delete(b);
Use BInterface as a filter for inherited classes to exclude undesirable methods. Liskov Substitution principle isn't violated in this case since an object of BInterface class is not an object of A class even though that an object of B class is an object of BInterface class.
If the methods are private in B, then they will remain hidden to a even if you use public inheritance.
Can't alter the visibility of the original method.
You could create a method in struct A with the same name and have that method be private, but that doesn't prevent the method from being called when an instance of struct A is being referenced by a variable of type B.
Why don't you make it Virtual in the base class and override it in its Children? (more help)