开发者

C++ method only visible when object cast to base class?

开发者 https://www.devze.com 2022-12-16 16:36 出处:网络
It must be something specific in my code, which I can\'t post. But maybe someone can suggest possible causes.

It must be something specific in my code, which I can't post. But maybe someone can suggest possible causes.

Basically I have:

class CParent
{
 public:
  void doIt(int x);
};
class CChild : public CParent
{
 public:
  void doIt(i开发者_如何学编程nt x,int y,int z);
};

CChild *pChild = ...
pChild->doIt(123); //FAILS compiler, no method found
CParent *pParent = pChild;
pParent->doIt(123); //works fine

How on earth?

EDIT: people are talking about shadowing/hiding. But the two versions of doIt have different numbers of parameters. Surely that can't confuse the compiler, overloads in child class which can't possibly be confused with the parent class version? Can it?

The compiler error I get is: error C2660: 'CChild::doIt' : function does not take 1 argument


You have shadowed a method. For example:

struct base
{
    void method(int);
    void method(float);
};

struct derived : base
{
    void method(int);
    // base::method(int) is not visible.
    // base::method(float) is not visible.
};

You can fix this with a using directive:

class derived : public base
{
    using base::method; // bring all of them in.

    void method(int);
    // base::method(int) is not visible.
    // base::method(float) is visible.
};

Since you seem insistent about the number of parameters, I'll address that. That doesn't change anything. Observe:

struct base
{
    void method(int){}
};

struct derived : base
{
    void method(int,int){}
    // method(int) is not visible.
};

struct derived_fixed : base
{
    using base::method;
    void method(int,int){}
};

int main(void)
{
    {
        derived d;

        d.method(1, 2); // will compile
        d.method(3); // will NOT compile
    }
    {
        derived_fixed d;

        d.method(1, 2); // will compile
        d.method(3); // will compile
    }
}

It will still be shadowed regardless of parameters or return types; it's simply the name that shadows. using base::<x>; will bring all of base's "<x>" methods into visibility.


You are hitting a classic problem. You need using CParent::doIt; in your CChild class. I'll scrounge up the duplicate questions.

Edit:

Here's my answer to essentially the same question: Overriding a Base's Overloaded Function in C++


I have never done this without having that method in the base class before. I think that adding "using CLASS::METHOD" in derived class will give you access to the other version of the overloaded method.

class CParent
{
 public:
  void doIt(int x);
};
class CChild : public CParent
{
 public:
  void doIt(int x,int y,int z);

  using CParent::doIt;
};


The problem is CChild doesn't actually inherit from CParent.

And so it doesn't have a doIt method that takes only one argument.


When you override a function in the derived class, only that function in the derived class is visible to the user of that class. The base class version becomes hidden.

Therefore, your pChild pointer calling doIt(int x) will fail since you are using a derived class pointer to call the base class function. The pParent pointer calling doIt(int x) will work since you are using a base class pointer to call the base class function. Even though you have a child object being pointed to by a parent pointer (upcasted), the class type here is determined by the declaration of the pointer which is a CParent.

To be able to call that base class function using the derived class pointer, you can:

  1. Qualify the base class name in the function call, as in the following:

    pChild->CParent::doIt(123);

  2. Use a using directive to bring the function name from the base class into the derived class, as seen in the previous posts.


I understand that this behavior is to give you flexibility to override the behavior of base class method in your derived class.

Lets assume that you have a function foo(int) in base class and you want to change the behavior of this function in your derived class. Now if the base class method is not hidden by your derived class method (which has same prototype as that of base class's method), it will introduce ambiguity in overload resolution.


The method in your child class has a different number of arguments than what you're trying to pass into it. Could it be related to that?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号