简体   繁体   English

C ++类和虚方法

[英]C++ Class and virtual method

I am having two problem about virtual methods. 关于虚拟方法,我有两个问题。

First: 第一:

class Parent
{
public:
    virtual void SHOW(int x = 5) { cout << "PARENT " << x << endl; }
};

class Child : public Parent
{
public:
    virtual void SHOW(int y = 10) { cout << "CHILD " << y << endl; }
};

int main()
{
    Child Y;

    Parent* P = &Y;
    P->SHOW();

    getch();  
    return 0;     
}

I think tt should be CHILD 10 but the result is CHILD 5 我认为tt应该是CHILD 10,但结果是CHILD 5

And another: 还有一个:

class Parent
{
public:
    virtual void SHOW() { cout << "PARENT" << endl; }
};

class Child : public Parent
{
private:
    virtual void SHOW() { cout << "CHILD" << endl; }
};

int main()
{
    Child Y;
    Parent* P = &Y;
    P->SHOW();

    getch();  
    return 0;     
}

It'll show CHILD on the screen. 它会在屏幕上显示CHILD I don't know how a private method which was called from outside? 我不知道如何从外部调用私有方法?

Thank you. 谢谢。 I'm learning English so.. :) 我在学英语.. :)

1) C++ Standard says 1)C ++标准说

A virtual function call (10.3) uses the default arguments in the declaration of the virtual function determined by the static type of the pointer or reference denoting the object. 虚函数调用(10.3)在虚函数的声明中使用默认参数,该声明由表示对象的指针或引用的静态类型确定。 An overriding function in a derived class does not acquire default arguments from the function it overrides. 派生类中的重写函数不会从其重写的函数中获取默认参数。

§8.3.6/10 §8.3.6/ 10

2) Overriding public virtual functions with private functions in C++ 2) 用C ++中的私有函数覆盖公共虚拟函数

A virtual function call uses the default arguments in the declaration of the virtual function determined by the static type of the pointer you use to call the function. 虚函数调用使用虚函数声明中的默认参数,该默认参数由用来调用函数的指针的静态类型确定。 In your case the static type of P is Parent although the dynamic type resolves to Child. 在您的情况下,P的静态类型为Parent,而动态类型解析为Child。 This is according to C++ standard. 这是根据C ++标准。

This is a good example of why it is typically best to make virtual functions private and public functions non-virtual . 这是一个很好的例子,说明为什么通常最好将虚拟功能设为私有,将公共功能设为非虚拟 Herb Sutter once called this the Non-Virtual Interface Idiom (NVI) . Herb Sutter曾经将其称为非虚拟接口惯用法(NVI)

Let's apply it to your code. 让我们将其应用于您的代码。 I'll also change the function name "SHOW" to "show", because all-uppercase in C++ usually denotes a macro. 我还将功能名称“ SHOW”更改为“ show”,因为C ++中的全大写字母通常表示一个宏。 Furthermore, I'll add a virtual destructor, because newbies are reading these questions and they shouldn't see a polymorphic class without one. 此外,我将添加一个虚拟析构函数,因为新手正在阅读这些问题,如果没有这些问题,他们将不会看到多态类。 Note that destructors are an exception to NVI. 请注意,析构函数是NVI的例外。

Here we go: 开始了:

class Parent
{
public:
    void show(int x = 5) { doShow(x); }
    virtual ~Parent() {}
private:
    virtual void doShow(int x) { cout << "PARENT " << x << endl; }
};

class Child : public Parent
{
private:
    virtual void doShow(int x) { cout << "CHILD " << x << endl; }
};

Default arguments are usually useful for code which uses the objects of a class. 默认参数通常对于使用类对象的代码很有用。 That code then uses the public functions. 该代码然后使用公共功能。

Parent *p = new Child;
p->show(); // here's where a default argument is a useful feature
delete p;

Inheriting classes, however, are interested in something completely different, namely in the virtual functions of the base class. 但是,继承类对完全不同的东西感兴趣,即对基类的虚函数感兴趣。 It turns out that you rarely feel the need for default arguments when you write the code for a subclass. 事实证明,为子类编写代码时,您很少会觉得不需要默认参数。

Bottom line: 底线:

  1. Default arguments and virtual functions shouldn't be mixed. 默认参数和虚函数不应混用。 There is an item for this in the famous Effective C++ book by Scott Meyers: "Never redefine an inherited default parameter value". 斯科特·迈耶斯(Scott Meyers)着名的有效C ++书中有一个与此有关的项目:“切勿重新定义继承的默认参数值”。 You should read that book. 你应该读那本书。
  2. Using NVI, you will typically not have this problem anyway, because it turns out default arguments are more of a thing for public functions, and with NVI, public functions aren't virtual. 使用NVI,您通常不会遇到任何问题,因为事实证明,默认参数对于公共函数来说更重要,而对于NVI,公共函数不是虚拟的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM