① 关于c++的编程
#include<iostream>
using namespace std;
struct STU{
char name[20];
int age,score;
};
void input(STU *s,int n){
int i;
for(i=0; i<n; i++){
cout <<"输入第 "<<i+1 <<" 个学生的姓名 年龄(16-28) 五分制成绩(0-5):";
cin >>s[i].name >>s[i].age >>s[i].score;
if(s[i].age <16 || s[i].age>28)
throw 1;
if(s[i].score <0 || s[i].score>5)
throw 2;
}
}
void main(){
STU s[3];
try{
input(s, 3);
cout <<"姓名\t年龄\t百分制成绩\n";
for(int i=0; i<3; i++){
cout <<s[i].name <<"\t" <<s[i].age <<"\t" <<s[i].score*20 <<endl;
}
}
catch(int e){
if(e==1)
cout <<"输入错误:年龄超出范围。\n";
if(e==2)
cout <<"输入错误:成绩超出范围。\n";
}
catch(...){
cout <<"其它异常。\n";
}
}
② 为什么非final方法不能进行inline优化
··inline是在编译的时候直接调用函数代码替换。
所以不用在运行的时候调用函数而因此优化。
所以inline需要在编译的时候就知道最后要用哪个函数。
显然,非final是不行的,因为在编译的时候不能知道。
而多态能知道运行的实际是哪个函数,那是在运行的时候才能知道,
运行时在编译之后。
一个代码编译通过但是不一定能运行,但是不能编译一定运行不了,这说明运行在编译之后。
③ 内联函数需要用inline关键字声明吗
要写!但注意的是当你的函数不符合内联函数的规则时,系统自动会把内联函数当做一半函数类处理!
④ inline和virtual冲突吗
其实内联函数和虚函数并不是冲突的,而是内联函数和使用虚机制调用的虚函数是冲突的.也就是说,虚函数可以静态调用也可以通过虚机制动态调用,所以如果虚函数通过静态调用的话就和内联函数是不冲突的.
总结:inline和virtual这两个标识符不是冲突的,而是在底层实现上存在冲突
⑤ C++ inline函数为什么不能继承
inline成员函数可以继承。
inline和类继承并没有关系。另外在类中直接定义函数体的成员函数默认就是inline的:
structA
{
intfoo()//这里等价于写inlineintfoo(),并且这个foo显然是可以继承的
{
return0;
}
};
因为inline函数另一个特性就是可以在不同编译单元里重复定义,而把成员函数体定义写在类定义里面会导致所有用这个类的编译单元都必须有函数体的定义,所以必须作为inline函数存在。
⑥ 为什么虚函数不应该是内联(inline)函数
常见的不能声明为虚函数的有:普通函数(非成员函数)、静态成员函数、内联成员函数、构造函数、友元函数。1、为什么C++不支持普通函数为虚函数? 普通函数(非成员函数)只能overload,不能被override,声明为虚函数也没有什么意思,因此编译器会在编译时绑定函数。2、为什么C++不支持构造函数为虚函数?这个原因很简单,主要是从语义上考虑,所以不支持。因为构造函数本来是为了明确初始化对象成员才产生的,然而virtual function主要是为了在不完全了解细节的情况下也能正确处理对象。另外,虚函数是在不同类型的对象产生不同的动作,现在对象还没有产生,如何使用虚函数来完成你想完成的动作。3、为什么C++不支持静态成员函数为虚函数? 静态成员函数对于每个类来说只有一份代码,所有的对象都共享这一份代码,他不归某个对象所有,所以他也没有动态绑定的必要性。4、为什么C++不支持内联成员函数为虚函数? 其实很简单,内联函数就是为了在代码中直接展开,减少函数调用话费的代价,虚函数是为了在继承后对象能够准确的执行自己的动作,这是不可能统一的。再说,inline函数在编译时被展开,虚函数在运行时才能动态的绑定函数。5、为什么C++不支持友元函数为虚函数?
⑦ C++中哪些函数不能声明为inline
内有虚函数调用的是不可以的,因为inline要求编译期展开,虚函数则是运行时确认,如果函数比较复杂,内有递归和循环,编译器也许会忽略inline请求。
⑧ 关于C++中虚函数的疑问
内联函数用关键是inline,这个关键字只是表示 一个要求,编译器并不承诺将inline修饰的函数作为内联函数。内联函数在编译时将函数体嵌入在每一个调用处。也就是说将一些功能简单规模小又使用频繁的函数设计为内联函数能节省开销,但是你将一个复杂的函数设置为内联函数的话编译器会自动将其转换为普通函数。
至于“内联函数不能声明为虚函数”,看下面代码:
class A
{
vritual void fun();//虚函数,实现代码略
};
class B:public A
{
void fun();//实现代码略
};
void main()
{
B b;
A * p;
p =& b;
p->fun();
}
在main函数里,如果基类没有将fun()声明为虚函数,则p->fun()根据指针类型(A * p)调用A::fun(),这个指针是编译的时候就知道的,编译器在进行编译的时候将fun()关联到A::fun(),这属于静态联编;
但是如果基类A将fun()函数声明为虚函数,则p->fun();将根据对象类型调用(B)调用B::fun(),上面的代码中对象是b,通常只有在运行的时候才能确定对象的类型,运行时候将根据对象类型将fun()关联到A::fun()或者B::fun(),这个属于动态联编。
这个就容易理解“内联函数不能声明为虚函数”,当虚函数是动态联编的时候编译器无法确定对象类型从而无法将函数体嵌入在每一个调用处。
这么解释能理解了吗?多看几遍你的教材里面相关概念再结合教材关于虚函数联编的例子就很好理解了。
⑨ 什么函数不能声明为虚函数
inline, static, constructor ,template 函数都不能 为虚函数,而析构函数可以。
为什么呢:
inline: 编译器替换; 而虚函数是为了解决运行期间绑定。
static:class 成员; 编译期间就给class了。
constructor: 构造函数表示要生成一个class的object;假设是virtual的,那就说不知道这个实例化derived还是based的class。但是类型实例化必须在编译期确定(否则编译器不知道到底是什么对象了)
template:模板实例是在 compile-time,virtual就意味着在run-time确定。这让编译器设计者为难了,这就是说虚函数表要指向各种版本的 template function 实例,代码设计者confuse,编译器设计者也觉得蛮烦。
⑩ C++编译器(Dev-C)是否会自动内联函数 对于什么样的函数即使标记inline也会拒绝内联
G++编译器是否会自动进行内联函数?
G++编译器是很先进的,编译的时候如果开启优化,G++会代码进行各种优化,如:对合适的函数进行内联(即便是没有添加inline关键字),对某些函数直接对其进行求值,除此之外G++编译器还可以对代码进行重排序 等等。编译器比你更了解硬件,所以只要允许它优化,他会尽量进行优化。你使用的Dev C++集成开发环境使用的c++编译器就是G++。
什么样的函数即使标记inline也无法内联?
比如函数体太大、太复杂的话(比如包含多重循环、包含递归调用),对其进行内联得不偿失,这时编译器就会忽略inline关键字,VC++编译器提供了强制内联函数的关键字,除非你非常了解硬件,不然最好让编译器来处。编译不对那些函数进行内联要看具体的编译器实现了。
inline关键字的有哪些作用?
inline关键字可以提示编译器对某个函数进行内联,并且强制函数使用内部链接。比如说你在头文件定义了某个函数,为了防止多重定义,你可以添加inline关键字来防止多重定义错误。
如果对硬件不是很了解,底层的代码优化还是留给编译器来处理。
看看下面的几个编译器优化函数的例子:
1.编译器直接对函数求值:
解释一下:
第一条和第二天指令分别将b和a的地址加载到寄存器rdx和rcx中
第三条指令将b的值加载到eax寄存器中
第四条指令将34存入b中
第五条指令将eax的值加1(eax保存了之前b的值)
第六条指令将eax的值存入a中
可以看出编译器将函数的两条语句换了位置,这种优化主要是优化代码的执行速度,有的CPU内存读写操作的的开销不一样,所以重新排序一下某些代码能够提高程序执行速度。