29 c++ methods struct function declare
例如,以下代码:
#include <iostream>
#include <string>
int main()
{
print("Hello!");
}
void print(std::string s) {
std::cout << s << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
在尝试构建时,我得到以下内容:
program.cpp: In function ‘int main()’:
program.cpp:6:16: error: ‘print’ was not declared in this scope
Run Code Online (Sandbox Code Playgroud)
这是有道理的.
那么为什么我可以在一个结构中进行类似的概念,但是不能为此大吼大叫呢?
struct Snake {
...
Snake() {
...
addBlock(Block(...));
}
void addBlock(Block block) {
...
}
void update() {
...
}
} snake1;
Run Code Online (Sandbox Code Playgroud)
我不仅没有得到警告,而且程序实际编译!没有错误!这只是结构的本质吗?这里发生了什么事?显然addBlock(Block)是在声明方法之前调用的.
Nir*_*rMH 15
甲struct在C++中实际上是一个class定义其内容在哪里public,除非通过包括一个受保护的指定,否则:或私人:部分.
当编译器看到class或时struct,它首先在块({})中消化所有声明,然后再对它们进行操作.
在常规方法的情况下,编译器还没有看到声明的类型.
v.o*_*dou 13
C++标准3.4.1:
0.4:
在全局范围内使用的名称,在任何函数,类或用户声明的命名空间之外,应在全局范围内使用之前声明.
这就是为什么在上述声明之前不能使用全局变量和函数的原因.
1.5:
在任何函数或类的定义之外的用户声明的命名空间中使用的名称应在其在该命名空间中使用之前或在其封装其命名空间的命名空间中使用之前声明.
同样的事情只是再写一次,因为.4段明确地将其说法局限于"全球化",这一段现在说"顺便说一下,它的真实性也在名人们......"
0.7:
在成员函数体或嵌套类定义29之外的类X的定义中使用的名称应以下列方式之一声明: - 在X类中使用之前或者是X(10.2)基类的成员之前,或者 - 如果X是类Y(9.7)的嵌套类,在Y中定义X之前,或者应该是Y的基类的成员(此查找依次应用于Y的封闭类,从最内层的封闭类,30或 - 如果X是本地类(9.8)或是本地类的嵌套类,在包含X类定义的块中定义类X之前,或者 - 如果X是命名空间N的成员,或者是N的成员的类的嵌套类,或者是在类X的定义之前是N的成员的函数的本地类中的本地类或嵌套类.名称空间N或N的封闭名称空间之一.
我认为这说明了所有不在cpu执行代码中的代码(例如声明性代码).
最后有趣的部分:
3.3.7类范围[basic.scope.class]
1以下规则描述了在类中声明的名称范围.
1)在类中声明的名称的潜在范围不仅包括名称声明点后面的声明性区域,还包括所有函数体,非静态数据成员的大括号或等于初始值,以及默认参数在那个类中(包括嵌套类中的这些东西).
2)在S类中使用的名称N应在其上下文中引用相同的声明,并在完成的S范围内重新评估.违反此规则不需要诊断.
3)如果类中的重新排序成员声明在(1)和(2)下产生备用有效程序,则程序格式错误,不需要诊断.
特别是,在最后一点,他们使用否定的方式来定义"任何排序是可能的",因为如果重新排序会改变查找,那么就会出现问题.它是一种消极的说法,"你可以重新排序任何东西,它可以,它不会改变任何东西".
有效地说,在一个班级中,宣言是以两阶段编译方式查找的.
" 为什么我可以在一个结构中执行类似的概念,但不会因此而大喊大叫?"
在一个struct或class定义中,您将向类提供公共接口,如果它出现在以下位置,则更容易理解,搜索和维护/更新该API:
对于可预测的顺序,人们有自己的风格,并且涉及到一些"艺术",但是例如我最多使用每个访问说明符一次,并且总是public在protected之前private,然后在那些我通常放置typedefs,const数据,构造函数,析构函数,变异/非const函数,const函数,statics,friends ....
为了最大限度地减少混乱,如果在类中定义了一个函数,它也可能没有事先声明.两者都倾向于混淆界面.
这与不是类成员的函数不同 - 喜欢自上而下编程的人确实使用函数声明并在文件中稍后隐藏定义 - 其中:
喜欢自下而上的编程风格的人不会理解被迫在类中单独声明或放弃通过访问说明符分组的经常冲突的做法
类在统计上更有可能具有许多非常短的函数,主要是因为它们提供封装并包装许多简单的数据成员访问或提供运算符重载,转换运算符,隐式构造函数和其他与非OO无关的便利特性,非会员职能.这使得声明和定义的持续强制分离对于许多类来说更加痛苦(在公共接口中不是那么多,其中定义可能在单独的文件中,但是对于例如支持当前转换单元的匿名命名空间中的类来说肯定是如此).
最好的做法是让课程不要挤满广泛的界面...你通常需要一个功能核心,然后是一些自由支配的便利功能,之后值得考虑可以作为非成员函数添加的内容.该std::string是一个经常声称有太多的成员函数,但我个人认为这是比较合理的.尽管如此,这也不同于声明库接口的头文件,其中可以预期穷举功能被挤在一起,使得甚至inline实现的分离更加令人满意.
| 归档时间: |
|
| 查看次数: |
1392 次 |
| 最近记录: |