我試圖學習 C PL 中的運算子多載。我做了一個如下所示的練習。我想要做的是為每個派生類多載 << 運算子并在我的主類上使用它。但每當我這樣做時,它只適用于基類。這里有什么問題?
班級員工:
class Employee {
public:
string name;
int id;
int exp_level;
double salary;
Employee() {
this->name = "";
this->id = 0;
this->exp_level = 0;
this->salary = 0.0;
}
~Employee() {
//WTF
}
virtual void calculateSalary() {
//CODE
}
virtual void registerX() {
//CODE
}
friend ostream& operator<<(ostream& os, const Employee& e) {
os << e.name << " " << e.exp_level << " " << e.id << " " << e.salary << endl;
return os;
}
};
技術類:
class Technical : public Employee {
public:
string profession;
Technical() {
this->profession = "";
}
~Technical() {
}
virtual void calculateSalary() {
//CODE
}
virtual void registerX() {
//CODE
}
friend ostream& operator<<(ostream& os, const Technical& e) {
os << e.name << " " << e.exp_level << " " << e.id << " " << e.salary << "Technical" << endl;
return os;
}
};
班工程師:
class Engineer : public Employee {
public:
Engineer() {
}
~Engineer() {
}
virtual void calculateSalary() {
//CODE
}
virtual void registerX() {
//CODE
}
friend ostream& operator<<(ostream& os, const Engineer& e) {
os << e.name << " " << e.exp_level << " " << e.id << " " << e.salary << "Engineer" << endl;
return os;
}
};
主要方法:
int main()
{
Employee* e = new Employee();
Employee* t = new Technical();
Employee* ee = new Engineer();
cout << *e << endl;
cout << *t << endl;
cout << *ee << endl;
}
輸出:
0 0 0
0 0 0
0 0 0
uj5u.com熱心網友回復:
C 根據函式引數的靜態型別Employee選擇最佳多載,因為在這種情況下是型別,所以會呼叫Employee's 。operator<<
如果您希望它在您有一個與其動態型別不匹配的靜態型別指標/參考時呼叫正確的版本,您將不得不使用虛擬函式或使用dynamic_casts/typeid來檢查具體的運行時型別(虛擬函式是最干凈的方法恕我直言)
示例:神螺栓
class Employee {
public:
virtual ~Employee() = default;
friend std::ostream& operator<<(std::ostream& os, const Employee& e) {
return e.put(os);
}
protected:
virtual std::ostream& put(std::ostream& os) const {
os << "Employee!";
return os;
}
};
class Technical : public Employee {
protected:
std::ostream& put(std::ostream& os) const override {
os << "Technical Employee!";
return os;
}
};
class Engineer : public Employee {
protected:
std::ostream& put(std::ostream& os) const override {
os << "Engineer Employee!";
return os;
}
};
int main() {
Employee* e = new Employee();
Employee* t = new Technical();
Employee* ee = new Engineer();
std::cout << *e << std::endl;
std::cout << *t << std::endl;
std::cout << *ee << std::endl;
delete ee;
delete t;
delete e;
}
會導致:
Employee!
Technical Employee!
Engineer Employee!
還要記住,一旦你在一個類中至少有 1 個虛函式,那么解構式幾乎肯定也是虛函式。
例如:
Employee* e = new Technical();
delete e;
如果解構式不是虛擬的,只會呼叫~Employee(),但不會呼叫。 ~Technical()
因此,每當您想通過指向其中一個基類的指標來洗掉物件時,解構式必須是虛擬的,否則就是未定義的行為。
uj5u.com熱心網友回復:
由于這些宣告
Employee* e = new Employee();
Employee* t = new Technical();
Employee* ee = new Engineer();
運算式*e, *t,的靜態型別*ee是Employee &. 所以運營商
friend ostream& operator<<(ostream& os, const Employee& e)
為所有三個物件呼叫。
使友元運算子 << “virtual” 的一種簡單方法是在每個類中定義一個虛函式,例如
virtual std::ostream & out( std::ostream & ) const;
并定義(唯一的)朋友運算子,如
friend ostream& operator<<(ostream& os, const Employee& e)
{
return e.out( os );
}
out需要在每個派生類中重新定義虛函式。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/411692.html
標籤:
上一篇:回傳具有更大引數的物件
下一篇:操作員=減慢模擬
