对于子功能,我的意思是给定一个类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
时出现错误。我该怎么解决?
答案 0 :(得分:-1)
Nested classes on cpprefrence.com
创建 outer 类时,就像其封闭类的任何成员一样,嵌套类可以访问封闭类可以访问的所有名称(私有,受保护等), 但 否则为 独立 ,并且没有对封闭类的
this
指针的特殊访问权限。
C ++不会创建 inner 类的实例。 inner 类也不会获得任何允许其使用 outer 类变量的变量。这些类必须显式声明彼此之间的访问(例如,通过实例化,引用或指针)。
所以Controller
需要两件事:
double& ref_c
或A& a
ref_c
或a
的构造函数然后在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 c
和struct 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();
};