[英]Overriding a member function with derived type in C++
是否可以使用類似於B::g()
或B::h()
顯示的派生類來覆蓋參數?
如果沒有,是否有一種明智的方法來實現同樣的目標?
為什么B::i()
不起作用是有道理的,但為什么其他的不起作用?
我的目標是在B::g()
使用r
作為類型Y
。
struct X {};
struct Y : X {};
struct A {
virtual void f(X q);
virtual void g(X& r);
virtual void h(X* s);
virtual X i(); // note: overridden function is 'virtual X A::i()'
virtual X* j();
};
struct B final : A {
void f(Y q) final; // error: 'void B::f(Y)' marked 'final', but is not virtual
void g(Y& r) final; // error: 'void B::g(Y&)' marked 'final', but is not virtual
void h(Y* s) final; // error: 'void B::h(Y*)' marked 'final', but is not virtual
Y i() final; // error: invalid covariant return type for 'virtual Y B::i()'
Y* j() final; // works
};
對於覆蓋函數參數列表必須相同,但在您的情況下,它不是。 這就是為什么它被認為是一個新函數並且不會覆蓋父函數中的函數。
所以你需要有這樣的東西來覆蓋:
struct A {
virtual void f(X q);
virtual void g(X& r);
virtual void h(X* s);
virtual X i();
virtual X* j();
};
struct B final : A {
void f(X q) override final;
void g(X& r) override final;
void h(X* s) override final;
X i() override final;
X* j() override final;
// Y* j() override final; <-- Also works because of covariant return
};
但請記住,您仍然可以將Y
傳遞給這些函數,因為Y
繼承了X
。
作為最后一個類成員的旁注, Y* j() override final;
也將起作用,因為它將是Covariant return 。 對於協變返回,您的返回需要是指針或引用。 但是你需要看看你是否真的需要它。
我的目標是在 B::g() 中使用 r 作為類型 Y。
您可以這樣做,但是B::g
不會覆蓋A::g
。 如果是這種情況,您需要使用相同的參數類型:
struct A {
virtual void g(X& r);
virtual ~A(){}
};
struct B : A {
void g(X& r) override;
};
要覆蓋標記為final
您需要在開頭添加虛擬。
例如: virtual void f(Y q) final;
B::i()
不起作用,因為返回類型與您嘗試覆蓋的函數的返回類型不同。
但是B::j()
起作用的原因是因為返回類型是一個指針,從技術上講,您可以返回一個指向存在的每種類型的指針。
只有當覆蓋函數具有與繼承函數相同的簽名(參數類型、 const
限定符等)時,才能覆蓋虛函數。
所以
struct A
{
virtual void f(X &);
};
struct B : public A
{
virtual void f(X &);
};
是可能的,但改變f()
的簽名,如
struct B : public A
{
virtual void f(Y &);
};
實際上隱藏了繼承的f()
而不是覆蓋它。 使用override
標識符,編譯器將檢測到這不是覆蓋,並診斷錯誤。
如果正確覆蓋,可以將Y
傳遞給A::f()
或B::f()
,因為您的Y
派生自X
。 但它是不可能重寫A::f()
使用具有不同類型的任何參數的函數A::f()
對於返回指向基類的指針(或者,引用)的函數有一種特殊情況——這可以被返回指向派生類的指針的函數覆蓋。 參數必須具有相同類型的約束。 所以你的B::j()
可以工作,因為Y
是從X
派生的。 就編譯器而言,像這樣的調用
X*x = pA->j(); // pA is of type A* but points at a B
沒問題,因為它仍然返回一個可以有效轉換為X *
的指針
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.