问题
I am very confused with the inheritance right now. I planned to simply override the initial value of a variable. In the following code i just inherit the base class and try to get it's name, which is saved as a string withing the class. I expected that the derived class can override this value, however it does not do it.
My expected out put was
Derived
Derived
However i get
Base
Base
What is the correct way to implement the following?
#include <iostream>
#include <string>
struct Base {
virtual ~Base() = default;
virtual void id(){
std::cout << id_ << std::endl;
}
std::string id_ = "Base";
};
struct Derived : public Base {
virtual ~Derived() = default;
std::string id_ = "Derived";
};
int main(){
Base* b = new Derived();
Derived* d = new Derived();
b->id();
d->id();
delete d;
delete b;
return 0;
}
回答1:
What is the correct way to implement the following?
Without meaning to sound difficult, it really depends on exactly what you want to achieve.
I'm going to make a guess that we're simply be asking an object what type it is, regardless of which interface we're calling on:
struct Base {
virtual ~Base() = default;
virtual const std::string id() const {
return "Base";
}
};
struct Derived : Base {
virtual const std::string id() const override {
return "Derived";
}
};
Here's another way:
struct Base {
virtual Base(std::string ident = "Base")
: _id(std::move(ident))
{}
virtual ~Base() = default;
std::string& id() const {
return _id;
}
private:
std::string _id;
};
struct Derived : Base {
Derived() : Base("Derived") {}
};
And another, using value is interface, but note that this will disable the assignment operator
struct Base {
virtual Base(std::string ident = "Base")
: id(std::move(ident))
{}
virtual ~Base() = default;
const std::string id;
};
struct Derived : Base {
Derived() : Base("Derived") {}
};
This list is by no means exhaustive.
回答2:
Virtual functions exist, not virtual member variables.
What you do in your Derived
class is define a new member variable id_
that hides it's parent. The id()
function, however, is referring to the id_
defined in that context.
If you want to override the behavior, you should override the id()
function:
class Derived: public Base {
std::string id() const override { return "Derived"; }
};
回答3:
Why not simply give Base
a constructor that sets id
and have Derived
call this constructor with its 'overridden' value? Boom: 'virtual data' according to the derived type.
Having said that, a virtual method might be more akin to encapsulation and provide opportunity for more elaborate behaviour later.
(Edit: I posted this as a comment and then converted it, by which point Richard had just beaten me to posting the answer. No copying has taken place!)
回答4:
Since function id() is virtual, in both case object pointer is Derived type only.
Base* b = new Derived(); // object type is Derived
b->id();
here b is pointer of type Derived but the "Derived" class has no implementation for id(), since there is no entry for id() in virtual lookup table for derived class object so it will call base class function id()
similarly other case also
Derived* d = new Derived(); //object type is Derived
d->id();
since id() method is not defined in the derived class it will call the base class id() only.
one more doubt is how you initialized the variable "id_" inside the class?
来源:https://stackoverflow.com/questions/34592361/override-initial-value-of-a-member-variable-of-base-class