Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Is there any harm in shadowing a parent constructor? It doesn't seem like anything is wrong, but my IDE is indicating and not warning me about it. Quick example

#include <iostream>
#include <string>

namespace NS1 {
 class A {
   public:
    A(){std::cout<<"I am A
";}
    virtual ~A(){}
 };
}

namespace NS2 {
 class A : public NS1::A{   
   public:
    A(): NS1::A() {}
    ~A(){}
 };
}

int main()
{
    NS2::A a;
}

It works as expected, but... is it bad to shadow?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
174 views
Welcome To Ask or Share your Answers For Others

1 Answer

There's nothing wrong with this code, except that it could possibly be improved by following the Rule Of Zero:

namespace NS2 {
  class A : public NS1::A {
  public:
    // Has implicitly declared default constructor, copy constructor,
    // move constructor, copy assignment, move assignment, and destructor.
  };
}

In fact, the constructor NS2::A::A does not "shadow" NS1::A::A at all.

A derived class does not inherit constructors from any base class by default. If you want that, you can say that it should with a declaration like using Base::Base;.

In your example, if NS2::A did not declare its default constructor A();, it would still get one implicitly with exactly the same behavior - but this is because a class with no user-declared constructors gets an implicitly declared/defined default constructor, not because NS1::A has such a constructor. If we add A(std::string); to NS1::A, this doesn't make it valid to create NS2::A("test").

#include <iostream>
#include <string>

namespace NS1 {
 class A {
   public:
     A(){std::cout<<"I am A
";}
     explicit A(std::string s) {
         std::cout << "Creating NS1::A from string '" << s << "'
";
     }
     virtual ~A(){}
 };
}

namespace NS2 {
 class A : public NS1::A {
 };
}

int main()
{
    NS2::A a;         // OK
    NS2::A b("test"); // Error, no matching constructor!
}

And then, if we add a similar A(std::string); to NS2::A, that's a different function. Its member initializer list will determine whether creating the NS1::A subobject uses the NS1::A::A(); default constructor, the NS1::A::A(std::string); constructor from string, or something else. But we wouldn't say that NS2::A::A(std::string); "hides" NS1::A::A(std::string); because the NS1::A constructor couldn't be used directly to initialize an NS2::A object even without the NS2::A::A(std::string); constructor present.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...