我试图从“内部”(本地)类的方法访问“外部”类的属性,但是我失败了。
无法编译
class outer
{
public:
std::string name;
class inner
{
public:
void hello();
};
void dostuff();
};
void outer::inner::hello(){std::cout << "Hello " << name << "\n";}
void outer::dostuff(){inner instanceInner; instanceInner.hello();}
int main()
{
outer instanceOuter;
instanceOuter.name = std::string("Alice");
instanceOuter.dostuff();
return 0;
}
编译错误:
9:21: error: invalid use of non-static data member 'outer::name'
21:53: error: from this location
我真的不希望name
成为静态成员,但我并不介意我的特定目的outer
是一个单身人士。所以我尝试了static std::string name;
并获得了
编译错误:
/tmp/ccqVKxC4.o: In function `outer::inner::hello()':
:(.text+0x4b): undefined reference to `outer::name'
/tmp/ccqVKxC4.o: In function `main':
:(.text.startup+0x1f): undefined reference to `outer::name'
collect2: error: ld returned 1 exit status
你能帮助我吗?
答案 0 :(得分:3)
您的问题在于hello()
功能。此处name
超出范围。它不属于您的inner
课程。不幸的是,你的内部类将无法看到你的外部类及其成员,因此:
void outer::inner::hello(){
std::cout << "Hello " << name << "\n";
}
会出现错误,告知您无法找到name
。
您可以执行以下操作:
#include <iostream>
#include <string>
class outer
{
public:
static std::string name;
class inner
{
public:
void hello();
};
void dostuff();
};
std::string outer::name = ""; // This is key. You need to instantiate outer's name somewhere.
void outer::inner::hello(){std::cout << "Hello " << outer::name << "\n";}
void outer::dostuff(){inner instanceInner; instanceInner.hello();}
int main()
{
outer instanceOuter;
instanceOuter.name = std::string("Alice");
instanceOuter.dostuff();
return 0;
}
<强>输出:强>
Hello Alice
答案 1 :(得分:2)
重复(稍加修改)我在另一个答案中提到的similar recent SO question:
C ++嵌套类不与其外部类共享数据 - 如果存在的话 如果是这样的话,内部类的每个实例都在一个 与外部的相应实例的一对一关系 类,因此不会添加额外的功能。相反,主要 嵌套类的目的是:
- 命名空间含义:
更有意义outer::inner
比outer_inner
- 根据C ++版本标准,嵌套类具有外部类实例的成员对象的额外可见性
- 也许是我不了解的其他人
醇>
以下是关于何时/为何在C ++中使用嵌套类的流行参考问题:Why would one use nested classes in C++?
在您的情况下,如果没有a)inner
类的特定实例({1}}将被访问,name
类无法引用数据outer
,或者b)对name
具有通用性的静态name
。第一个解决方案要求outer
类构造为引用inner
类:
outer
其中inner (const outer& _o) : o(_o) {}
是o
类型的私有成员。然后写const outer&
函数
hello
或者,如果你想让void outer::inner::hello(){std::cout << "Hello " << o.name << "\n";}
静态,那么它是一个未定义的引用,因为你必须把
name
在某个编译单元中,否则静态成员未定义。
但是,在任何一种情况下,我担心您滥用嵌套类。它在您的代码中有什么用途?为什么数据和成员函数必须在外层和嵌套类之间分开?你确定一堂课不能更好地为你的目的服务吗?