簡體   English   中英

C++ 陰影父構造函數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM