I have a base class Base and a number of sub classes BaseDerivate1 .. BaseDerivateN. Part of my code is generic and supports any of the sub classes by accessing the used class via a define BASE_DERIVATE.
I now need to add a static function that the child classes can declare but don't have to. For derived classes that declare StaticFunc(), I want to call it. In all other cases, I want to call the fallback function Base::StaticFunc(). The call looks like this:
#define BASE_DERIVATE BaseDerivate1 // or some other child class
// somewhere else:
BASE_DERIVATE::StaticFunc();
So I intentionally use name hiding here. The StaticFunc is never called from within the class. The question I have is: Is this supported by the C++ standard or would this lead to compiler errors for some compilers. Also: Is there a better way to do "static inheritance"? I am stuck with the define BASE_DERIVATE concept however.
This will "just work":
#include <iostream>
class Base {
public: static void foo() { std::cout << "Base::foo()\n"; }
};
class Derived1 : public Base { };
class Derived2 : public Base {
public: static void foo() { std::cout << "Derived2::foo()\n"; }
};
int main() {
Derived1::foo(); // prints "Base::foo()"
Derived2::foo(); // prints "Derived2::foo()"
}
It's the use of regular name shadowing, which works just the same for static members. The Base static implemenation is still available from Derived2 by means of rather funny syntax:
Derived2::Base::foo();
Related
I have designed a class which uses overloaded member functions that call each other such that functions with additional arguments modify member variables that the original function relies on. It works as expected/intended when inheritance is not involved, but I found myself reusing the code often enough to want to create an abstract class.
I did this by having the original member function exit with an error in the abstract class, but still implementing the overloaded functions that modify member variables before calling the original function. This is done with the intent of only having to override the original function in my derived classes. However, when I create a derived class from this abstract class and supposedly override the member function, the functions that are not overridden still seem to be using the abstract class's definition of the member function-- the one that exits with an error. Here is a minimal example that causes the unexpected behavior.
#include <iostream>
#include <string>
#include <cstdlib>
class Base
{
// this class exists only to be derived from
public:
void write_message()
{
std::cerr << "Base is an abstract class not intended for direct use in"
<< " programs." << std::endl;
exit(1);
}
void write_message(std::string NewMessage)
{
Message = NewMessage;
write_message();
}
protected:
std::string Message = "This is the default message";
};
class Derived : public Base
{
public:
using Base::write_message;
void write_message()
{
std::cout << Message << std::endl;
}
private:
// intentionally blank
};
int main() {
Derived MyObject;
MyObject.write_message("Here is a modified message");
return 0;
}
As I'm sure is clear from this example, I am already aware of the common pitfall involving inheriting overloaded member functions which is topic of other questions on this site, which is needing to have using Base::write_message in my derived class. A couple of those questions include: this and this. What those questions don't address is this issue involving the overriding of write_message not working the way I expect it to.
What is missing here? I can't reason out why Base::write_message() would be used of Derived::write_message when calling MyObject.write_message("Here is a modified message"); in the code above.
I am using cpp17 and g++12.2.1 on linux.
What you should use is the virtual methods. Without them, it's not the overriding, but so called hiding. That's, you may define a method within the derived class which will have the same calling semantics as in base class, but it will hide the method from the base class.
Here is rewritten your example:
#include <iostream>
#include <string>
#include <cstdlib>
class Base
{
// this class exists only to be derived from
public:
virtual ~Base() = default; // It's better to have a virtual destructor if there is at least one virtual method.
virtual void write_message() = 0; // Pure virtual method. It defines the calling interface only and must be overridden to be used.
void write_message(const std::string& NewMessage) // It's better to use the const-reference in order to escape unneeded copying.
{
Message = NewMessage;
write_message(); // Call the _implementation_
}
protected:
std::string Message = "This is the default message";
};
class Derived : public Base
{
public:
using Base::write_message;
void write_message() override // 'override' key-word ensures that we are overriding 'right' method and helps against of typos etc.
{
std::cout << Message << std::endl;
}
private:
// intentionally blank
};
int main() {
// Yes, it points to the Base, but because of virtuality...
Base* MyObject = new Derived;
MyObject->write_message("Here is a modified message"); // ... it invokes the Derived::write_message() here.
delete MyObject; // Don't forget to free the memory.
return EXIT_SUCCESS;
}
Today i tried to instanciate an inner class while passing my outer class to it and while i am in the namespace of the outer class:
I'm using Visual Studo 2013.
Code looks like this : (watch the ^^)
class Base
{
public:
virtual void foo(){ cout << "foo" };
};
class object
{
class Derived : public Base
{
object& o;
public:
Derived(object& o) : o(o){}
virtual void foo(){ cout << "bar" };
}derived(*this);
// ^^^^^^
};
The derived class inheriting something does not affect anything for this example here as far as i tested. (only in here for context reasons , see below)
On this ^^ point i recieve error:
no appropriate default constructor available
Intellisense warns me, that it expects type specification.
I also tried passing a pointer (of course i changed construktors then, too)but same reaction.
For protokoll i tried quite a lot of variations and research by now, but i cannot isolate a clear answer to my problem.
Is the "this" pointer not usable here ? How can i pass myself then at this point ?
For Background (only if you're interested):
I tried to write Code for Keybinding in an Application. To pass
functions to the Keys i use an "Interface" of class KeyFunction (Base
class resembles it).
I now want to give classes (object) the possibility to declare it's
own KeyFunction(Derived) and , more important, pass ressources(object)
with it, in a way that functions can work on them (since i can only
use void pointers, because they are later stored in an array for the
bindings) I already achieved this task with other code which i think
is to long to post here, though. By experimenting i stumbled across
this problem.
Your compilation error has nothing to do with your class hierarchy, but with the simple fact that this is not how you go about constructing a class instance.
Try actually declaring a class member, and a class constructor:
class Base
{
public:
virtual void foo(){ }
};
class object
{
class Derived : public Base
{
object& o;
public:
Derived(object& o) : o(o){}
virtual void foo(){ }
};
Derived derived;
object() : derived(*this)
{
}
};
So I recently accidentally called some virtual functions from the constructor of a base class, i.e. Calling virtual functions inside constructors.
I realise that I should not do this because overrides of the virtual function will not be called, but how can I achieve some similar functionality? My use-case is that I want a particular function to be run whenever an object is constructed, and I don't want people who write derived classes to have to worry about what this is doing (because of course they could call this thing in their derived class constructor). But, the function that needs to be called in-turn happens to call a virtual function, which I want to allow the derived class the ability to override if they want.
But because a virtual function gets called, I can't just stick this function in the constructor of the base class and have it get run automatically that way. So I seem to be stuck.
Is there some other way to achieve what I want?
edit: I happen to be using the CRTP to access other methods in the derived class from the base class, can I perhaps use that instead of virtual functions in the constructor? Or is much the same issue present then? I guess perhaps it can work if the function being called is static?
edit2: Also just found this similar question: Call virtual method immediately after construction
If really needed, and you have access to the factory.
You may do something like:
template <typename Derived, typename ... Args>
std::unique_ptr<Derived> Make(Args&&... args)
{
auto derived = std::make_unique<Derived>(std::forward<Args>(args));
derived->init(); // virtual call
return derived;
}
There is no simple way to do this. One option would be to use so-called virtual constructor idiom, hide all constructors of the base class, and instead expose static 'create' - which will dynamically create an object, call your virtual override on it and return (smart)pointer.
This is ugly, and what is more important, constrains you to dynamically created objects, which is not the best thing.
However, the best solution is to use as little of OOP as possible. C++ strength (contrary to popular belief) is in it's non-OOP specific traits. Think about it - the only family of polymorphic classess inside standard library are streams, which everybody hate (because they are polymorphic!)
I want a particular function to be run whenever an object is constructed, [... it] in-turn happens to call a virtual function, which I want to allow the derived class the ability to override if they want.
This can be easily done if you're willing to live with two restrictions:
the constructors in the entire class hierarchy must be non-public, and thus
a factory template class must be used to construct the derived class.
Here, the "particular function" is Base::check, and the virtual function is Base::method.
First, we establish the base class. It has to fulfill only two requirements:
It must befriend MakeBase, its checker class. I assume that you want the Base::check method to be private and only usable by the factory. If it's public, you won't need MakeBase, of course.
The constructor must be protected.
https://github.com/KubaO/stackoverflown/tree/master/questions/imbue-constructor-35658459
#include <iostream>
#include <utility>
#include <type_traits>
using namespace std;
class Base {
friend class MakeBase;
void check() {
cout << "check()" << endl;
method();
}
protected:
Base() { cout << "Base()" << endl; }
public:
virtual ~Base() {}
virtual void method() {}
};
The templated CRTP factory derives from a base class that's friends with Base and thus has access to the private checker method; it also has access to the protected constructors in order to construct any of the derived classes.
class MakeBase {
protected:
static void check(Base * b) { b->check(); }
};
The factory class can issue a readable compile-time error message if you inadvertently use it on a class not derived from Base:
template <class C> class Make : public C, MakeBase {
public:
template <typename... Args> Make(Args&&... args) : C(std::forward<Args>(args)...) {
static_assert(std::is_base_of<Base, C>::value,
"Make requires a class derived from Base");
check(this);
}
};
The derived classes must have a protected constructor:
class Derived : public Base {
int a;
protected:
Derived(int a) : a(a) { cout << "Derived() " << endl; }
void method() override { cout << ">" << a << "<" << endl; }
};
int main()
{
Make<Derived> d(3);
}
Output:
Base()
Derived()
check()
>3<
If you take a look at how others solved this problem, you will notice that they simply transferred the responsibility of calling the initialization function to client. Take MFC’s CWnd, for instance: you have the constructor and you have Create, a virtual function that you must call to have a proper CWnd instantiation: “these are my rules: construct, then initialize; obey, or you’ll get in trouble”.
Yes, it is error prone, but it is better than the alternative: “It has been suggested that this rule is an implementation artifact. It is not so. In fact, it would be noticeably easier to implement the unsafe rule of calling virtual functions from constructors exactly as from other functions. However, that would imply that no virtual function could be written to rely on invariants established by base classes. That would be a terrible mess.” - Stroustrup. What he meant, I reckon, is that it would be easier to set the virtual table pointer to point to the VT of derived class instead of keep changing it to the VT of current class as your constructor call goes from base down.
I realise that I should not do this because overrides of the virtual function will not be called,...
Assuming that the call to a virtual function would work the way you want, you shouldn't do this because of the invariants.
class B // written by you
{
public:
B() { f(); }
virtual void f() {}
};
class D : public B // written by client
{
int* p;
public:
D() : p( new int ) {}
void f() override { *p = 10; } // relies on correct initialization of p
};
int main()
{
D d;
return 0;
}
What if it would be possible to call D::f from B via VT of D? You will use an uninitialized pointer, which will most likely result in a crash.
...but how can I achieve some similar functionality?
If you are willing to break the rules, I guess that it might be possible to get the address of desired virtual table and call the virtual function from constructor.
Seems you want this, or need more details.
class B
{
void templateMethod()
{
foo();
bar();
}
virtual void foo() = 0;
virtual void bar() = 0;
};
class D : public B
{
public:
D()
{
templateMethod();
}
virtual void foo()
{
cout << "D::foo()";
}
virtual void bar()
{
cout << "D::bar()";
}
};
I made a class with virtual function f() then in the derived class I rewrote it like the following f(int) why can't I access the base class function throw the child instance ?
class B{
public:
B(){cout<<"B const, ";}
virtual void vf2(){cout<<"b.Vf2, ";}
};
class C:public B{
public:
C(){cout<<"C const, ";}
void vf2(int){cout<<"c.Vf2, ";}
};
int main()
{
C c;
c.vf2();//error should be vf2(2)
}
You have to do using B::vf2 so that the function is considered during name lookup. Otherwise as soon as the compiler finds a function name that matches while traversing the inheritance tree from child -> parent -> grand parent etc etc., the traversal stops.
class C:public B{
public:
using B::vf2;
C(){cout<<"C const, ";}
void vf2(int){cout<<"c.Vf2, ";}
};
You are encountering name hiding. Here is an explanation of why it happens ?
In C++, a derived class hides any base class member of the same name. You can still access the base class member by explicitly qualifying it though:
int main()
{
C c;
c.B::vf2();
}
You were caught by name hiding.
Name hiding creeps up everywhere in C++:
int a = 0
int main(int argc, char* argv[]) {
std::string a;
for (int i = 0; i != argc; ++i) {
a += argc[i]; // okay, refers to std::string a; not int a;
a += " ";
}
}
And it also appears with Base and Derived classes.
The idea behind name hiding is robustness in the face of changes. If this didn't exist, in this particular case, then consider what would happen to:
class Base {
};
class Derived: public Base {
public:
void foo(int i) {
std::cout << i << "\n";
}
};
int main() {
Derived d;
d.foo(1.0);
}
If I were to add a foo overload to Base that were a better match (ie, taking a double directly):
void Base::foo(double i) {
sleep(i);
}
Now, instead of printing 1, this program would sleep for 1 second!
This would be crazy right ? It would mean that anytime you wish to extend a base class, you need to look at all the derived classes and make sure you don't accidentally steal some method calls from them!!
To be able to extend a base class without ruining the derived classes, name hiding comes into play.
The using directive allows you to import the methods you truly need in your derived class and the rest are safely ignored. This is a white-listing approach.
When you overload a member function in a base class with a version in the derived class the base class function is hidden. That is, you need to either explicitly qualify calls to the base class function or you need a using declaration to make the base class function visible via objects of the derived class:
struct base {
void foo();
void bar();
};
struct derived: base {
void foo(int);
using base::foo;
void bar(int);
};
int main() {
derived().foo(); // OK: using declaration was used
derived().bar(); // ERROR: the base class version is hidden
derived().base::bar(); // OK: ... but can be accessed if explicitly requested
}
The reason this is done is that it was considered confusing and/or dangerous when a member function is declared by a derived function but a potenially better match is selected from a base class (obviously, this only really applies to member functions with the same number of arguments). There is also a pitfall when the base class used to not have a certain member function: you don't want you program to suddenly call a different member function just because a member function is being added to the base class.
The main annoyance with hiding member functions from bases is when there is a set of public virtual functions and you only want to override one of them in a derived class. Although just adding the override doesn't change the interface using a pointer or a reference to the base class, the derived class can possibly not used in a natural way. The conventional work-around for this to have public, non-virtual overload which dispatch to protected virtual functions. The virtual member function in the various facets in the C++ standard library are an example of this technique.
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.