首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

问两个why:为什么关键字static friend不能出现在定义里面

2014-01-05 
问两个why:为啥关键字static friend不能出现在定义里面?1)友元关键字friend:在声明里面必须要求有,在定义

问两个why:为啥关键字static friend不能出现在定义里面?
1)友元关键字friend:在声明里面必须要求有,在定义时候不能有,否则报编译错误//问下why设计成这样?

2)静态数据成员static:在声明里面必须要求有,在定义的时候不能有,否则会报编译错误。//问下why设计成这样?

3)缺省参数:放在在声明里面,在定义里面不能出现。林锐认为:参数默认值与定义无关且方便修改////问下why设计成这样?

4)inline:原则上声明和定义的时候都可以出现,但是林锐认为inline不能出现在函数声明中,用户没有必要知道函数是否内联。//问下why设计成这样?


[解决办法]
1、友元函数表示的是这个函数不是我的成员,但可以使用我的成员数据。换个角度来说,也就是有点特殊的普通函数,普通函数定义分离后脱离了类,那么就是一个普通函数,为什么需要friend。

2、看看lippman的《深度探索C++对象模型》,对C++的对象模型来说,static函数其实是非成员函数的形式,他是在类外的,所以不存在同时指定static和::。对象模型有点复杂,等你学会C++的基础后可以一点点去深入了解。

3、等你做过大型项目你就知道了,对于C/C++来说,管理头文件比管理实现文件更重要。人们更愿意去维护、查看头文件而不是实现文件。所以放在声明里是合理的。你会去别人写的一堆代码里找缺省,还是直接看头文件?

4、inline其实只是编译器的一种优化,而且inline有个问题,当代码比较复杂时,inline会失去作用。所以对用户来说是否是inline的一点也不重要。
[解决办法]
1. 友元是个相互作用的关键字,只存在于表明双方关系的场景中(旨在表明谁是谁的什么),单方面不能使用。

2. 不懂。 坐等高人。

3. 默认形参放到实现文件中,不是不好,是没有用的,得到编译时错误。

4. 其实,我个人认为林锐博士的这句话,很容易引起误会。我想他的意思是,用inline的时候,你就不要把声明和实现的分开了,就把实现当成一种分明放到头文件中好了。 否则,只放把inline放到实现中,是没有用的,它可能仅在它所在的编译单元起作用的(当然,这就跟编译器实现很相关了),对于别的cpp文件来说是看见inline的。

引用:
1、友元函数表示的是这个函数不是我的成员,但可以使用我的成员数据。换个角度来说,也就是有点特殊的普通函数,普通函数定义分离后脱离了类,那么就是一个普通函数,为什么需要friend。

2、看看lippman的《深度探索C++对象模型》,对C++的对象模型来说,static函数其实是非成员函数的形式,他是在类外的,所以不存在同时指定static和::。对象模型有点复杂,等你学会C++的基础后可以一点点去深入了解。

3、等你做过大型项目你就知道了,对于C/C++来说,管理头文件比管理实现文件更重要。人们更愿意去维护、查看头文件而不是实现文件。所以放在声明里是合理的。你会去别人写的一堆代码里找缺省,还是直接看头文件?

4、inline其实只是编译器的一种优化,而且inline有个问题,当代码比较复杂时,inline会失去作用。所以对用户来说是否是inline的一点也不重要。

[解决办法]
引用:
1. 友元是个相互作用的关键字,只存在于表明双方关系的场景中(旨在表明谁是谁的什么),单方面不能使用。

2. 不懂。 坐等高人。

3. 默认形参放到实现文件中,不是不好,是没有用的,得到编译时错误。

4. 其实,我个人认为林锐博士的这句话,很容易引起误会。我想他的意思是,用inline的时候,你就不要把声明和实现的分开了,就把实现当成一种分明放到头文件中好了。 否则,只放把inline放到实现中,是没有用的,它可能仅在它所在的编译单元起作用的(当然,这就跟编译器实现很相关了),对于别的cpp文件来说是看见inline的。
第三点应该不会有编译错误的吧,至少VS下没有报错,标准上应该没说吧。除非你在声明和定义中同时指定缺省。不过最好是放在头文件中,可以避免不必要的麻烦。举个例子:
//A.h
class A{
public:
A(int i);
private:
int i;
};
//main.cpp
#include "A.h"

int main(){
A a;//此时只有A(int i);看不到缺省,编译失败了。
return 0;
}

A::A(int i=0):i(i){}


第四点的话,一般inline都是放头文件里的吧,不然inline的效果就没有了。
[解决办法]
1) 定义的时候,该函数或者类,不在把他定义为友元的作用域中。
   友元的声明只能在类作用域中,才有效,表示该函数(友元函数)或者类(友元类)
   可以访问把它声明为友元的类的私有成员,保护成员。 

2)外部加static 就称为类外作用域的静态成员了,或者说造成二义性。
   内部不加,则是类的非静态成员。

3)默认参数,应该视为函数声明的一部分。
   二者不能同时定义,默认参数,是为了防止定义不同的默认参数。
   个人认为,应该不允许定义的时候定义默认参数才行。
   
   也可能是,为了inline 函数着想,因为 inline 不需要单独声明,只有定义就行了。

4)inline 函数定义,等同于声明,没有必要单独声明。
   因为可能整个函数都会嵌入调用处,而且嵌入的时候必须知道,inline 函数定义,而不是声明。

   不需要再有个声明,表示有这么一个函数。
   
   没有定义,有这个声明也没有用,不能实现inline
   有这个定义,定义本身就起到声明的作用,何必再声明一遍。

[解决办法]
类的成员变量,
     const 加不加,表示不同的对象(常量,变量),同时出现,构成命名冲突。
类内 static 加了表示静态成员,不加表示非静态成员。

类外不加static,表示只是类作用域的 static 变量;
类外,只是定义一下,类作用域的静态成员变量而已,所以不加。

当初,也许认为,类静态成员变量,
不是类对象的成员,所以不在类内定义。




[解决办法]
关于static有个说法:被static修饰的标识符只在其所在作用域中有效,并在其所在作用域有效其间一直有效(英文按记忆翻译,措辞可能不准)。 所以,static在类成员声明时用说明该成员在类中有效,如果在类外再来一遍语义就冲突了。

friend是指被修饰的类或函数拥有访问当前类的私有成员的权限,如果用在类外就没法解释了,总不能说被修饰的类或函数可以访问全局的私有成员吧?

默认参数并不影响当前函数的行为,而是影响调用方,调用方代码如果没有显示指定具体默认值的参数的值,则编译器需要在编译时使用默认参数补齐。 因此默认参数应该放在调用方看得到的地方。

对于 inline ,我并不是很理解林锐的说法。 inline理论上应该是给调用方(用户)作参考的,告诉调用方(用户)当前函数应该被内联,所以我以为,inline应该在函数声明上才有意义。 当然话说回来, 现在很多编译器在文档中都粗暴的表示它们会无视任何inline明示与暗示, 理由是程序员们太笨了,根本不能正确评估是否应该inline,所以这事还是交给它们这些聪明的编译器来全权处理吧。 另外,从语法上讲,类成员函数内联实现即表示该函数拥有inline修饰,这个应该也算是声明上的吧。

热点排行