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 7 years ago.
Improve this question
When asked if private members of class B are inherited by D, a class derived from B, people emphatically say: yes they are inherited but not accessible directly, only indirectly for instance via public methods in the base class. OK, but what is the difference between not being inherited and not being directly accessible? For instance class X (NOT derived from B) also has access to private members of B via public methods of B, even though X doesn't inherit anything from B.
what is the difference between
1) not being inherited and
2) being inherited and not being directly accessible.
what is not clear?
The difference is in the class layout.
struct B {
private: char buf[1024];
};
struct D : B { };
Here, sizeof(D) >= sizeof(B). It's still there, i.e. it's clearly inherited.
If the base class has virtual functions that can be overriden by the derived class, clearly this is an important difference to a class having access to a base class instance but not inheriting from it:
class B
{
public:
virtual ~B() {}
int get_a() const
{
do_something();
return a;
}
virtual void do_something() const
{
std::cout << "In B\n";
}
private:
int a{};
};
class D : public B
{
virtual void do_something() const
{
std::cout << "In D\n";
}
};
int main()
{
D d;
d.get_a();
}
If the base class does not have any virtual functions, then the usefulness of inheriting from it is less clear. In fact, it is perhaps best not to inherit from it (at least publicly) as the lack of a virtual destructor could cause some problems, and it should be made a member variable instead.
Related
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 days ago.
Improve this question
I have a question not only about c++, even though my example is about c++.
if I have a base class let's call it Mother and 2 childs, call respectively Child1 and Child2.
The classes have a method get_name.
My question is which version is better (pro/cons) between:
class Mother
{
virtual char* get_name() const = 0;
virtual ~Mother() = default;
}
class Child1: public Mother
{
virtual char* get_name() const override {return "child1";}
}
class Child2: public Mother
{
virtual char* get_name() const override {return "child2";}
}
and
class Mother
{
Mother(char* name): name(name) {}
char* get_name() const {return this->name;}
char* name;
}
class Child1: public Mother
{
Child1(): Mother("Child1") {}
}
class Child2: public Mother
{
Child1(): Mother("Child2") {}
}
In the first case I use polymorphism and in the second case I store the data (the name). I'd like to know the advantage(s) and disadvantage(s) of each methods.
Thank you
I tried to find an answer on internet but I haven't so far.
The first One is Polymorphism albeit wrong that goes for the second one as well(I'll explain it below), since you didn't inherit the Base Class Mother.
In the first case I use polymorphism and in the second case I store
the data (the name). I'd like to know the advantage(s) and
disadvantage(s) of each methods. Thank you
I'll Return the answer in a form of a Question, are you going to call the method through a Base Pointer? if yes, Do you want them to behave differently in each cases? Then you should use the concept of the polymorphism.
One of the Major advantage of Polymorphism is to have the Derived Classes behave differently using the Same Function name when called from a base pointer like below,Godbolt here..
#include <iostream>
class Base
{
public:
Base(){}
virtual ~Base(){}
virtual int SomeFunction(){ return 0;}
protected:
int m_nX;
int m_nY;
};
class Derived1 : public Base
{
public:
Derived1(int x, int y){m_nX = x; m_nY = y;}
~Derived1(){}
virtual int SomeFunction()
{
return m_nX * m_nY;
}
};
class Derived2 : public Base
{
public:
Derived2(int x, int y){m_nX = x; m_nY = y;}
~Derived2(){}
virtual int SomeFunction()
{
return m_nX + m_nY;
}
};
int main()
{
Derived1 bDerived1(10,10);
Derived2 bDerived2(10,10);
Base* bBase = &bDerived1;
printf("The Result of Some Function From Derived 1 is %d\n",bBase->SomeFunction());
bBase = &bDerived2;
printf("The Result of Some Function From Derived 2 is %d\n",bBase->SomeFunction());
return 0;
}
One of the biggest disadvantage is misuse, when a simple inheritance would do. Like you've said in your question. You can simply store the data since you are only fetching it and not doing anything differently.
The second code is wrong since you don't need to explicitly Construct the base class since it would be constructed automatically when a Derived Class is constructed using it's Default Constructor. What you would do is to either call up a function that set's a value to the base class member, or if you want it to be done During the object's construction, you can simply assign it inside the constructor itself. Like above.
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 5 years ago.
Improve this question
If I have a class, let's call it class A that is derived from a class called class B, is it possible to return an object of class B from my derived object of class A?
If I have a class, let's call it Class A that is derived from a class called Class B, is it possible to return an object of Class B from my derived object of Class A?
Sure that's possible:
class B {
// ...
};
class A : public B {
public:
// Not that this is explicitly necessary:
B& getAsB() { return *this; }
};
It's also valid to write simply:
A a;
B& b = a;
Though doing something like
A a;
B b = a;
will create a copy and slice your original A to B.
Yes, it is possible, but it's not remarkable in any way.
struct B {}; // using struct instead of class for convenience
struct A // may or may not inherit from B
{
B ReturnSomeObject()
{
return B();
}
};
int main()
{
A object1;
B object2 = object1.ReturnSomeObject();
}
Here, even though there is no inheritance, a method in class A can return an object of class B. If you add inheritance
struct A: B
{
...
};
it still works.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have a base class A and a few derived classes B, C and D, that all have a method DoSomething(), which is virtual in the base class method (it's implemented in all sub classes as well as in the base class).
I have a problem, that the derived class B uses the method from the base class A. This may be the result of bad design, but I do not see the problem as the implementation is pretty straight forward.
An object of class B that is created in the following
A* a = new B();
If I call the method DoSomething() for this object, the method of the base class is used:
a->DoSomething(); //Results in Base class method being called.
But I expect/want that the method of class B is used. Can you tell me what's wrong?
According to the symptoms that you describe:
either you have forgotten the virtual keyword in the base class member definition.
or you have a subtle difference in you signature in the derived class.
The way forward would be to indicate in the derived class that the function is an override:
class A {
...
virtual void DoSometing();
};
class D : public A {
...
void DoSomething() override;
};
In this case, in case of mismatch you'll get a clear compiler error message.
The following example implements what you asked for.
#include <iostream>
class A
{
public:
virtual void DoSomething()
{
std::cout << "A::DoSomething" << std::endl;
}
};
class B : public A
{
public:
virtual void DoSomething()
{
std::cout << "B::DoSomething" << std::endl;
}
};
int main(int argc, char **argv)
{
A *a = new B();
a->DoSomething();
delete(a);
return 0;
}
Output:
B::DoSomething
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 8 years ago.
Improve this question
I have a base class that defines methods as virtual and those methods has nothing inside, just the declaration. I have a class that derives from the base class and doesn't implements all the methods and here is where the problem appears. If we call a method that isn't implemented on the derived class, but in the base, it crashes.
Example (it crashes):
#include <iostream>
class Foo
{
public:
virtual std::string ref() {}
};
class Bar : public Foo {};
int main(int argc, char ** argv)
{
auto foo = new Bar;
auto bar = foo->ref();
return 0;
}
Q: What is the best solution in this case.
1) - Return a default (empty) value.
virtual std::string ref()
{
return "";
}
2) - Throw an exception that you can't call methods directly from the base class.
virtual std::string ref()
{
throw std::runtime_error(":(");
}
Thank you.
This is what pure virtuals are for:
virtual std::string ref() = 0;
now the compiler won't let you instantiate an instance of a derived type that doesn't define that function.
If we call a method that isn't implemented on the derived class, but
in the base, it crashes.
This does not strictly apply to your example code:
virtual std::string ref() {}
An implementation is there; you get a crash because the implementation doesn't return anything. The same would likely happen here, for example:
#include <string>
std::string f() {}
int main()
{
std::string x = f();
x = "";
}
(I say "likely" because it's undefined behaviour, so the crash is not guaranteed.)
As for your problem:
If you need to call functions which do not conceptually exist, then you have a design problem; chances are that your base class tries to fulfill too many responsibilities at the same time.
Otherwise, use abstract classes. You can make a class abstract by declaring at least one function pure virtual:
class Foo
{
public:
virtual std::string ref() = 0; // pure virtual function
};
Please note three further things:
You almost certainly need a virtual destructor in your base class.
Except of the destructor, consider making your public functions non-virtual and your virtual functions private, the public non-virtual ones calling the private virtual ones.
Your function looks like a candidate for a const function.
Final example:
class Foo
{
public:
virtual ~Foo() {}
std::string ref() const { return refImpl(); }
private:
virtual std::string refImpl() const = 0;
};
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 8 years ago.
Improve this question
So, I have class called A with a prototyped function x. B, C, and D are deriving from A, so the derived classes are having function x also protyped.
Now I want that not every class has function x defined.
How is that possible in C++?
It's against the OOP principles. Inheritance means an is-a relationship. In your example, B, C and D are a kind of A. If A has method x, the others should have also.
If it's not true, x is not really a method of A (but one of it's descendants')
If x should be only accessible from A instead, make it private:
private: void x() {}
You might want to declare x as pure virtual function, e.g.:
virtual void x() = 0;
Making assumptions about what you are asking since every class that derives from A will have x defined. If what you are asking for is that classes B, C and D are implemented in terms of A (i.e. they will utilize the functions of A but cannot be considered an instance of A), you can specify protected or private inheritance of A in B,C, and D.
Example code with this approach might be:
#include <iostream>
class A
{
public:
void x()
{
std::cout << "Hello from A::x" << std::endl;
}
};
class B : protected A
{
public:
};
class C : protected A
{
public:
void x()
{
std::cout << "Hello from C::x" << std::endl;
}
};
class D : public A
{
public:
};
int main(int argc, char **argv)
{
//B instance_of_B;
//instance_of_B.x(); // Will cause a compiler error
C instance_of_C;
instance_of_C.x(); // Will print Hello from C::x
D instance_of_D;
instance_of_D.x(); // will print Hello from A::x
}