[英]C++ shadowing parent constructor
遮蔽父構造函數有什么害處嗎? 似乎沒有任何問題,但我的 IDE 正在指示並且沒有警告我。 快速示例
#include <iostream>
#include <string>
namespace NS1 {
class A {
public:
A(){std::cout<<"I am A\n";}
virtual ~A(){}
};
}
namespace NS2 {
class A : public NS1::A{
public:
A(): NS1::A() {}
~A(){}
};
}
int main()
{
NS2::A a;
}
它按預期工作,但是......陰影不好嗎?
這段代碼沒有任何問題,除了可以通過遵循零規則來改進它:
namespace NS2 {
class A : public NS1::A {
public:
// Has implicitly declared default constructor, copy constructor,
// move constructor, copy assignment, move assignment, and destructor.
};
}
事實上,構造函數NS2::A::A
根本沒有“隱藏” NS1::A::A
。
默認情況下,派生的 class 不會從任何基礎 class 繼承構造函數。 如果你願意,你可以說它應該像using Base::Base;
這樣的聲明。 .
在您的示例中,如果NS2::A
未聲明其默認構造函數A();
,它仍然會以完全相同的行為隱式獲得一個 - 但這是因為沒有用戶聲明的構造函數的 class 會獲得一個隱式聲明/定義的默認構造函數,而不是因為NS1::A
有這樣的構造函數。 如果我們添加A(std::string);
到NS1::A
,這並不能使創建NS2::A("test")
有效。
#include <iostream>
#include <string>
namespace NS1 {
class A {
public:
A(){std::cout<<"I am A\n";}
explicit A(std::string s) {
std::cout << "Creating NS1::A from string '" << s << "'\n";
}
virtual ~A(){}
};
}
namespace NS2 {
class A : public NS1::A {
};
}
int main()
{
NS2::A a; // OK
NS2::A b("test"); // Error, no matching constructor!
}
然后,如果我們添加一個類似A(std::string);
到NS2::A
,這是一個不同的 function。 它的成員初始化器列表將確定創建NS1::A
子對象是否使用NS1::A::A();
默認構造函數, NS1::A::A(std::string);
來自字符串或其他東西的構造函數。 但我們不會說NS2::A::A(std::string);
“隱藏” NS1::A::A(std::string);
因為NS1::A
構造函數不能直接用於初始化NS2::A
object 即使沒有NS2::A::A(std::string);
構造函數存在。
您的編譯器/IDE可能意味着:
namespace X {
struct A {
A() = default;
};
}
struct B : X::A {
B () : A() { // <- you can use just A, as opposed to X::A here
A a; // <- also here
}
};
struct A : X::A {
A () : X::A() { // <- you cannot use unqualified A here to refer to X::A,
// because it is shadowed by class's own name
X::A a; // <- neither here
}
};
它沒有什么特別有害的,因為您始終可以使用限定名稱。 所以我會說警告它是沒有意義的,如果編譯器這樣做是一個錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.