如何在课程中使用子功能

时间:2018-12-30 20:49:07

标签: c++

对于子功能,我的意思是给定一个类A和实例a,我可以调用

a.control.fire();

其中控件是包含函数的某种类型的结构。但是,另外的要求是fire()可以访问a的变量。我尝试了以下方法:

#pragma once

using namespace std;

class A {
public:
    double c;

    struct Controller {
        double fire () { return c * 2};
    };

    Controller control;

    A();
};

现在,我确实可以调用a.control.fire(),但是在尝试访问c时出现错误。我该怎么解决?

2 个答案:

答案 0 :(得分:-1)

Nested classes on cpprefrence.com

  

就像其封闭类的任何成员一样,嵌套类可以访问封闭类可以访问的所有名称(私有,受保护等), 否则为 独立 ,并且没有对封闭类的this指针的特殊访问权限。

创建 outer 类时,

C ++不会创建 inner 类的实例。 inner 类也不会获得任何允许其使用 outer 类变量的变量。这些类必须显式声明彼此之间的访问(例如,通过实例化,引用或指针)。

所以Controller需要两件事:

  • 对变量c或其类的实例的引用:double& ref_cA& a
  • 初始化ref_ca的构造函数

然后在A的构造函数controller中用c*this进行初始化(也可以使用聚合初始化)。


示例:

class Outer // Enclosing
{
public:
    double c;

    struct Inner // Nested
    {
        const Outer& a;

        double fire() const { return a.c * 2; };
    };

    Inner control { *this };

    Outer();
};

答案 1 :(得分:-2)

class A内有两个防水容器:double cstruct Controller。从一个人的内心无法到达另一个人。 C ++抽象层中的规则是,您不能从内而外走。您只能从外面进入。Controller::fire()只能看到Controller本身内部的东西。它不了解外界。

通过一起摆脱Controller,可以改善代码。这是一个“墙”,因为它位于该墙内,因此阻止了您的功能看到double c

    #pragma once

using namespace std;

class A {
public:
    double c;

    double fire () { return c * 2};


    A();
};

另一种方法是通过“墙”提供一些“门”,这是一种将double c放入Controller中以使其对{{ 1}}。我的意思是声明一个构造函数double fire()并传递一个指针。

Controller::Controller()

如另一个答案中所述,您还可以在C ++中使用引用。在这种情况下,这实际上会更好。

#pragma once

using namespace std;

class A {
public:
    double c;

    struct Controller {
        Controller(double* ptr) : c_ptr(ptr) {}
        double * c_ptr;
        double fire () { return *c_ptr * 2};
    };

    Controller control(&c);

    A();
};