Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 months ago.
Improve this question
I seek an explanation for why member-classes don't work like member-functions.
Here's a minimal example:
#include <iostream>
class Base
{
public:
Base ():my_stuff ()
{
};
struct Stuff
{
Stuff ()
{
std::cout << "Base created Stuff" << std::endl;
};
};
Stuff my_stuff;
};
class Derived: Base
{
public:
struct Stuff
{
Stuff ()
{
std::cout << "Derived created Stuff" << std::endl;
};
};
};
int
main ()
{
Base the_base;
Derived the_derived;
return (0);
}
Output:
Base created Stuff
Base created Stuff
vs. Desired output:
Base created Stuff
Derived created Stuff
A number of similar examples work similarly, unless I overload the constructor explictly. Let's say I want to avoid that, as in my case, because I have a ton of derived classes.
I am skeptical there is a solution, otherwise perhaps the compiler would allow me to write "virtual class" as a specifier, which is actually my aim.
I acknowledge this may sound unreasonable, yet Python allows it and I recently made the switch :)
Thanks in advance!
Edit: comments have pointed out the question is not clear, so I'll give it another shot.
What is considered good practice (or a good pattern) for related classes A, B, C... that use components X, Y, Z... respectively, but in the same way?
Take iterator as an example. Each standard container implements its own iterator. My expectation is therefore that a common container ancestor exists, having as a member the base class for iterator. If it is so, how is it accomplished?
Thanks again
Virtual (inner) class is not possible in C++.
template might help:
template <typename T>
struct Stuff;
template <typename Tag>
class StuffBase
{
Stuff<Tag> my_stuff;
public:
StuffBase() = default;
};
class BaseTag{};
class DerivedTag{};
template <>
struct Stuff<BaseTag>
{
Stuff() { std::cout << "Base created Stuff" << std::endl; }
};
template <>
struct Stuff<DerivedTag>
{
Stuff() { std::cout << "Derived created Stuff" << std::endl; }
};
using Base = StuffBase<BaseTag>;
using Derived = StuffBase<DerivedTag>;
Demo
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
What is the advantage of using polymorphism in C++ over using mere inheritance, as it seems to me that i can't achieve with polymorphism something what I can't do with mere inheritance. Also in both ways i can make use of virtual functions. Is there a situation where polymorphism can do something which is not reachable by using mere inheritance?
These 2 exemples (first - polymorphism, second - mere inheritance) allowed me to reach the same results, so im wondering what else can polympthism provide me with, which cannot be achieved by doing by normal inheritance.
Polymorphism code:
#include <iostream>
using namespace std;
class Kryptonians
{
public:
void setPower(int p) {power = p;}
void gotHit(int h){power -=h;}
virtual void displayPower(){std::cout << "power is: " << power << "\n";}
protected:
int power;
};
class Supergirl: public Kryptonians
{
public:
void displayPower(){
std::cout << "Supergirl's power is: " << power << "\n";}
};
class Superman: public Kryptonians
{
public:
void displayPower(){
std::cout << "Superman's power is: " << power << "\n";}
};
int main()
{
Supergirl sup;
Superman super;
Kryptonians *supergirl = ⊃
Kryptonians *superman = &super;
supergirl->setPower(100);
supergirl->displayPower();
superman->setPower(100);
superman->gotHit(50);
superman->displayPower();
supergirl->displayPower();
}
Mere inhetirance code:
#include <iostream>
using namespace std;
class Kryptonians
{
public:
void setPower(int p) {power = p;}
void gotHit(int h){power -=h;}
virtual void displayPower(){std::cout << "power is: " << power << "\n";}
protected:
int power;
};
class Supergirl: public Kryptonians
{
public:
void displayPower(){
std::cout << "Supergirl's power is: " << power << "\n";}
};
class Superman: public Kryptonians
{
public:
void displayPower(){
std::cout << "Superman's power is: " << power << "\n";}
};
int main()
{
Supergirl supergirl;
supergirl.setPower(100);
supergirl.displayPower();
Superman superman;
superman.setPower(100);
superman.gotHit(50);
superman.displayPower();
supergirl.displayPower();
}
My question is about why to use polymorphism at all, when one could do pretty well avoid using it, and limiting themselves to only use inheritance. As user463035818 stated, basicly there is no situation where polymorphism can do something which is not reachable by using inheritance. So as i understand, using polymprphism is the prefered design patter?
At least in C++, the primary reason to use inheritance is for polymorphism. There is also something called "implementation inheritance", but it's frowned upon as a general rule.
The canonical example of polymorphism would involve a virtual function, which is declared in a base class and implemented in a derived class:
class interface {
public:
virtual void foo() = 0;
};
class implementation : public interface {
public:
virtual void foo() override {
// do something useful here
}
};
In this case, the base class doesn't actually implement foo at all, it just declares an interface, so that any code that works with that interface can work with any derivative of that base class.
Implementation inheritance is primarily for cases where you have a number of derived classes that all do slight variations on the same general things, so you can implement the common behavior in the case class, and each derived class only implements the areas in which it varies from that common base.
One fairly well known example of implementation inheritance in C++ is std::iterator. This is a base class that contains on virtual functions (so no polymorphism). It's sole purpose is to provide some typedefs that iterators are expected to provide. The types are all typically related, so a derived class can typically pass a single template parameter to the base class, and get all the necessary typedefs:
class my_iterator : public std::iterator<std::output_iterator_tag, void, void, void, void> {
// ...
};
This saves the implementer of the iterator from typing code like this:
using size_type = std::size_t;
using difference_type = std::ptr_diff_t;
using value_type = T;
using reference = T&;
using pointer = T*;
It does save some typing--but not a whole lot, and what it saves is almost all simple boiler-plate anyway.
As mentioned above, however, this is frowned upon as a rule--in fact, std::iterator is officially deprecated, so it may disappear from some future version of the standard.
Polymorphism
In computer science, polymorphism is a programming language feature
that allows values of different data types to be handled in a uniform
manner.
For example:
void foo(bar& b) {
b.do_something();
};
Treating objects of different types the same is called polymorphism. b can be of any type as long as it inherits bar.
Inheritance
Inheritance is the system in object oriented programming that allows
objects to support operations defined by anterior types without having
to provide their own definition. It is the major vector for
polymorphism in object-oriented programming
For example:
struct bar {
virtual void do_something() = 0;
virtual ~bar(){}
};
struct foobar1 : bar {
virtual void do_something() override {
std::cout << "muh";
}
};
struct foobar2 : bar {
virtual void do_something() override {
std::cout << "meh";
}
};
Different types can inherit the same base class such that they can be used polymorphically.
Is there a situation where polymorphism can do something which is not
reachable by using inheritance?
No.
Well....Yes.
Some usage of tempaltes can be considered as compile time polymorphism. If you are interested in compile time polymorpishm you should take a look at the CRTP
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
The intention is to detect whether the Template type parameter D is derived from Template type parameter B. The below code has private static methods in the class IsDerivedHelper. The question is How does the static method inside the Helper class works? It doesn't have a definition in it.
#include<iostream>
#include<type_traits>
using namespace std;
class IOne
{
private:
public:
IOne() = delete;
virtual void print() = 0;
};
class One :public IOne
{
public:
One() = default;
virtual void print()
{
cout << "printed from class One" << endl;
}
};
class Two
{
};
template<typename D, typename B> class IsDerivedHelper
{
class No{};
class Yes { No no[3]; };
static Yes Test(B*);
static No Test(...);
public:
enum { Is = sizeof(Test(static_cast<D*>(0))) == sizeof(Yes) };
};
void main()
{
auto v = IsDerivedHelper<One, IOne>::Is; // Value is 1
// auto v = IsDerivedHelper<Two, IOne>::Is; // Value is 0
if (v)
{
cout << "Is derived" << endl;
}
else
{
cout << "Not a derived." << endl;
}
}
Thanks in advance.
THis works at compile time really , the core is the decision of which IsDerivedHelper::Test overload to use
this call here
sizeof(Test(static_cast<D*>(0)))
Will return the sizeof the return value of which overload is chosen. All at compile time.
The two overloads are
static Yes Test(B*);
static No Test(...);
The first one is used if the argument passed is derived from B.
The second one is used in any other case. ... means 'any args'
the static methods are never called, everything is evaluated at compile time.
It is a clever set of tricks
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I want to write a generic interface. I need a list of different objects in a std::vector. Each of this objects has a other type but the same interface.
For example:
struct Base
{
std::string name;
virtual void doWork(???, ???);
virtual void print(???,???);
};
struct ObjA : Base
{
void doWork(???,???) override
{
std::cout << "Hello\n";
};
void print(???,???) override
{
std::cout << "Hey\n";
};
}
struct ObjB : Base
{
void doWork(???,???) override { std::cout << "Hello\n"; };
void print(???,??? ) override { std::cout << "Hey\n"; };
}
But i don't know the type of ???,???. Since it is not possible to use virtual in combination with template's I'm searching for an elegant way.
Is it possible to solve this at compile time ?
You could do this with variable arguments.
In Base pass an integer for the number of arguments you are going to pass and then the variable arguments.
Then use va_arg to get the actual parameters.
struct Base
{
std::string name;
virtual void doWork(int i, ...)
{
}
};
struct ObjB : Base
{
void doWork(int i, ...) override
{
va_list ap;
va_start(ap, i);
int x = va_arg(ap, int);
std::cout << x << std::endl;
float f = va_arg(ap, float);
std::cout << x << std::endl;
va_end(ap);
}
};
Base *base = new ObjB;
base->doWork(2, 10, 3.f);
This question could be marked as duplicated!
But because you stated: "Since it is not possible to ...."
and asked: "Is it possible to solve this at compile time?"
Please refer to this answer:
Can a C++ class member function template be virtual?
Your unknown parameter types (???) smell like they also need to share a common interface to provide any useful information to your methods.
That would solve the problem in an elegant way, but obviously not at compile time.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Is it good idea to replace virtual multiple inheritance (diamon) with teplates inheritence (linear)? For example I have this class diagram :
IBase
/ \
/ \
IExtendedBase BaseImpl
\ /
ExtendedImpl
I know that I can implement it with virtual inheritance. But can I use templates in order to make this diagram linear?
class IBase
{
public:
virtual std::string name() = 0;
};
template<typename T>
class BaseImpl : public T
{
public:
virtual std::string name() override
{
return "BaseCommonImpl";
}
};
template<typename T>
class IExtendedBase : public T
{
public:
virtual std::string extended_name() = 0;
};
template<typename T>
class ExtendedBaseImpl : public T
{
public:
virtual std::string extended_name() override
{
return "ExtendedBaseImpl";
}
};
Now with typedef I can specialize ExtendedBase
typedef IExtendedBase<BaseImpl<IBase>> _ExtendedBase;
typedef ExtendedBaseImpl<_ExtendedBase> _ExtendedBaseImpl;
Which method is better? Virtual inheritance or template inheritance?
While you can obtain similar results using these two different approaches (multiple inheritance vs. template), there are important semantic differences.
Unfortunately, you do not give enough information to recommend an objective choice. So here some considerations:
Multiple inheritance approach
Multiple inheritance is meant for enforcing effective separation of concerns.
This approach should be preferred if in your case ExtendedImpl is-a IExtendBase and simulatneously is-a BaseImpl, but both inheritance relations are independent.
It has the inconvenience of a slight performance overhead in some cases (casting for example).
But it has the advantage of allowing your ExtendedImpl to be used where any of its bases could be used. And in addition, it allows for dynamic, runtime based polymorphism (if any of its base has a virtual member function).
Template approach
Templates are meant for generic programming. This approach is to be prefereed if your ExtendedImpl is really generic, and the "bases" are more parameters for your generic concept, rather than a concept that is extended further.
Template would have here the approach of a slightly better performance (single inheritance). But you don't implement the original concept of your initial schema. And you don't have the flexibility of dynamic polymorphism.
If the relation between the types would not be of generic nature, you might induce here undesired dependencies. For example here, IExtendedBase would inherit from BaseImpl. This could be ok in many cases. But it could be completely unnatural in other cases, leading to lasting desing issues in the maintenance phase.
Conclusion
Now it's up to you to decide which advantage and inconvenience fits best your specific case. If needed, you could edit your question giving more precise indication about the context and your intentions, and I'll adapt the answer
accordingly.
This question is a request for opinions, so it will probably get closed down by a moderator.
Before it does, my advice would be to favour the approach that avoids multiple inheritance:
#include <iostream>
#include <string>
class IBase
{
public:
virtual std::string name() = 0;
};
class IExtendedBase : public IBase
{
public:
virtual std::string extended_name() = 0;
};
template<typename T>
class BaseImpl : public T
{
public:
virtual std::string name() override
{
return "BaseCommonImpl";
}
};
template<typename T>
class ExtendedBaseImpl : public T
{
using inherited = T;
public:
virtual std::string extended_name() override
{
return "ExtendedBaseImpl";
}
// optionally override name if you wish
std::string name() override {
return inherited::name() + "(extended)";
}
};
typedef BaseImpl<IBase> Base;
typedef ExtendedBaseImpl<BaseImpl<IExtendedBase>> ExtendedBase;
using namespace std;
int main()
{
Base a;
a.name();
cout << a.name() << endl;
ExtendedBase b;
cout << b.extended_name() << endl;
cout << b.name() << endl;
}
Please accept my apologies in advance for the somewhat long-winded question. This is the minimal self-contained example I could come up with... I'm pretty sure there must be some obvious/nice/neat solution to this problem, but I'm currently not able to see it.
Ok, here's the problem: Imagine the following situation (nb. a compileable version of the code is available at http://goo.gl/dhRNex). Suppose
struct Thing1 {
public:
void bar(class Implementation1 &i) {
i.baz();
}
// ...various other methods like bar()
};
struct Thing2 {
public:
void bar(class Implementation2 &i) {
i.qux();
}
// ...various other methods like bar()
};
are given. Unfortunately, these classes are fixed, i.e., can not be changed/refactored.
However, Implementation1 and Implementation2 are changeable. These two classes share a lot of similar code, so it seems natural to put the shared code in a common base class. However, the code is dependent the type of Thing used, but there is no common base class for Thing1 and Thing2, so it seems also natural to use templates. Thus, I came up with the following solution for the base class
template<class T, class S>
struct ImplementationBase {
public:
S *self;
void foo() {
T thing;
thing.bar(*self);
}
// ...lots more shared code like foo()
};
and concrete implementations
struct Implementation1 : public ImplementationBase<class Thing1, class Implementation1> {
public:
Implementation1() {
self = this;
}
void baz() {
std::cout << "Qux!" << std::endl;
}
};
struct Implementation2 : public ImplementationBase<class Thing2, class Implementation2> {
public:
Implementation2() {
self = this;
}
void qux() {
std::cout << "Qux!" << std::endl;
}
};
Ideally, one would use this instead of self in foo, but the problem is that this is of type ImplementationBase<class Thing1, class Implementation1>, but Implementation1 is required. Obviously, the whole thing is quite a mess and the Implementation and Thing classes are too tightly coupled, but I cannot see an easy way out without being able to refactor the Thing classes. So, finally, my questions are:
Is there a better alternative to using the self trick above?
Is there a design that would solve this problem in a better manner? (I have a feeling, there is, but that I'm missing something obvious)
If you have made it this far, thanks a lot for taking the time and reading the whole story and my apologies again for this long-winded question.
You're already using CRTP so you don't need the self at all:
template<class T, class S>
struct ImplementationBase {
public:
S* getThis() { return static_cast<S*>(this); }
void foo() {
T thing;
thing.bar(*getThis());
}
// ...lots more shared code like foo()
};