仿xss网站搭建,一个空间安装多个网站,开发一个网址要多少钱,wordpress编辑导航栏一.什么函数不能声明为虚函数?
常见的不能声明为虚函数的有:普通函数(非成员函数):静态成员函数;内联成员函数;构造函数;友元函数。
1.为什么C不支持普通函数为虚函数?普通函数(非成员函数)只能被overload#xff0c;不能被override#xff0c;声明为虚函数也没有什么意思…一.什么函数不能声明为虚函数?
常见的不能声明为虚函数的有:普通函数(非成员函数):静态成员函数;内联成员函数;构造函数;友元函数。
1.为什么C不支持普通函数为虚函数?普通函数(非成员函数)只能被overload不能被override声明为虚函数也没有什么意思因此编译器会在编译时邦定函数。
2.为什么C不支持构造函数为虚函数?
因为构造函数本来就是为了明确初始化对象成员才产生的虚函数表的指针是在构造函数中初始化的主要是从语义上考虑所以不支持。
3.为什么C不支持内联成员函数为虚函数?
其实很简单那内联函数就是为了在代码中直接展开减少函数调用花费的代价虚函数是为了在继承后对象能够准确的执行自己的动作这是不可能统一的。(再说了inline函数在编译时被展开虚函数在运行时才能动态的邦定函数)。
4.为什么C不支持静态成员函数为虛函数?这也很简单静态成员函数对于每个类来说只有一份代码所有的对象都共享这一份代码他也没有要动态邦定的必要性。
5.为什么C不支持友元函数为虚函数? 因为C不支持友元函数的继承对于没有继承特性的函数没有虚函数的说法。
二.纯虚函数指的是什么?
纯虚函数是一种特殊的虚函数格式一般如下 由于在很多情况下基类中不能对虚函数给出有意义的实现只能把函数的实现留给派生类。例如动物作为一个基类可以派生出老虎、孔雀等子类但是动物本身生成对象不合情理此时就可以将动物类中的函数定义为纯虚函数如果基类中有纯虚函数那么在子类中必须实现这个纯虚函数否则子类将无法被实例化也无法实现多态。 含有纯虚函数的类称为抽象类抽象类不能生成对象。纯虚函数永远不会被调用它们主要用来统一管理子类对象。
三.基类的构造函数/析构函数是否能被派生类继承?
基类的构造函数析构函数不能被派生类继承。
基类的构造函数不能被派生类继承派生类中需要声明自己的构造函数。设计派生类的构造函数时不仅要考虑派生类所增加的数据成员初始化
也要考虑基类的数据成员的初始化。声明构造函数时只需要对本类中新增成员进行初始化对继承来的基类成员的初始化需要调用基类构造函数完成。
基类的析构函数也不能被派生类继承派生类需要自行声明析构函数。声明方法与一般(无继承关系时)类的析构函数相同不需要显式地调用基类的析构函数
系统会自动隐式调用。需要注意的是析构函数的调用次序与构造函数相反。
四.初始化列表和构造函数初始化的区别?
构造函数初始化列表以一个冒号开始接着是以逗号分隔的数据成员列表每个数据成员后面跟一个放在括号中的初始化式。例如:
Example::Example():ival(0)dva1(0.0){} //ival(0) 和dva1是类的两个数据成员
上面的例子和下面不用初始化列表的构造函数看似没什么区别:
Example::Example{ival 0;dva7 0.0;
}
的确这两个构造函数的结果是一样的。但区别在于:上面的构造函数(使用初始化列表的构造函数显示的初始化类的成员;而没使用初始化列表的构造函数是对类的成员赋值并没有进行显示的初始化。
初始化和赋值对内置类型的成员没有什么大的区别像上面的任一个构造函数都可以。但有的时候必须用带有初始化列表的构造函数:
1.成员类型是没有默认构造函数的类。若没有提供显示初始化式则编译器隐式使用成员类型的默认构造函数若类没有默认构造函数则编译器尝试使用默认构造函数将会失败。
2.const成员或引用类型的员。因为const对象或引用类型只能初始化不能对他们赋值.
五.C中有那些情况只能用初始化列表而不能用赋值?
构造函数初始化列表以一个冒号开始接着是以逗号分隔的数据成员列表每个数据成员后面都跟一个放在括号中的初始化式。
例如Example:Example ival(o,dva(0.0)其中ival与dva是类的两个数据成员。
在C语言中赋值与初始化列表的原理不一样赋值是删除原值赋予新值初始化列表开辟空间和初始化是同时完成的直接给予一个值.
所以在C中赋值与初始化列表的使用情况也不一样只能用初始化列表而不能用赋值的情况-般有以下3种:
1.当类中含有 const(常量)、reference(引用)成员变量时只能初始化不能对它们进行赋值。常量不能被赋值只能被初始化
所以必须在初始化列表中完成C的引用也一定要初始化所以必须在初始化列表中完成。
2.派生类在构造函数中要对自身成员初始化也要对继承过来的基类成员进行初始化当基类没有默认构造函数的时候
通过在派生类的构造函数初始化列表中调用基类的构造函数实现。
3.如果成员类型是没有默认构造函数的类也只能使用初始化列表。若没有提供显式初始化时
则编译器隐式使用成员类型的默认构造函数此时编译器尝试使用默认构造函数将会失败.
六.构造函数没有返回值那么如何得知对象是否构造成功?
这里的“构造”不单指分配对象本身的内存而是指在建立对象时做的初始化操作(如打开文件、连接数据库等)
因为构造函数没有返回值所以通知对象的构造失败的唯一方法就是在构造函数中抛出异常。
构造函数中抛出异常将导致对象的析构函数不被执行当对象发生部分构造时已经构造完毕的子对象将会逆序地被析构。
七.C语言宏中的#和##的区别
区别
“#”将其后面的宏参数进行字符串化操作。
“##”在带参数的宏定义中将两个子串(token)联接起来从而形成一个新的子串。
例子一
#include stdio.h
#define paster( n ) printf( token #n %d, token##n )
int main()
{int token9 10;paster(9);return 0;
}
paster(9)宏展开结果
printf(token9 %d, token9);
输出结果
token9 10
例子二
#define hehe(x,y) x##y
int main()
{char string[] hello world;printf(%s\n, hehe(str, ing));return 0;
}
输出结果
hello world
八.在C语言中为什么 static变量只初始化一次?
对于所有的对象(不仅仅是静态对象)初始化都只有一次而由于静态变量具有“记忆”功能初始化后一直都没有被销毁都会保存在内存区域中所以不会再次初始化。存放在静态区的变量的生命周期一般比较长
它与整个程序“同生死、共存亡所以它只需初始化一次。而auto变量即自动变量由于它存放在栈区一旦函数调用结束就会立刻被销毁。
九.函数指针和指针函数的区别
函数指针Function Pointer 函数指针是指向函数的指针。通过函数指针可以间接调用函数这在实现回调机制和动态链接时非常有用。
指针函数Pointer Function 指针函数是返回类型为指针的函数。也就是说该函数会返回一个指针而这个指针可以指向某种类型的数据。
函数指针示例:
#include stdio.h// 定义两个简单的加法和乘法函数
int add(int a, int b)
{return a b;
}int multiply(int a, int b)
{return a * b;
}int main()
{// 定义一个指向函数的指针int (*operation)(int, int);// 将指针指向加法函数operation add;printf(Addition: %d\n, operation(5, 3)); // 输出Addition: 8// 将指针指向乘法函数operation multiply;printf(Multiplication: %d\n, operation(5, 3)); // 输出Multiplication: 15return 0;
}
指针函数示例:
#include stdio.h
#include stdlib.h
// 定义一个函数返回指向int的指针
int* getArray(int size)
{// 在堆上分配内存int *array (int*)malloc(size * sizeof(int));for (int i 0; i size; i) {array[i] i 1; // 初始化数组}return array; // 返回数组的指针
}// 主函数
int main()
{int size 5;// 获取数组的指针int *myArray getArray(size);// 打印数组内容for (int i 0; i size; i) {printf(%d , myArray[i]);}printf(\n);// 释放分配的内存free(myArray);return 0;
}
十.在头文件中定义静态变量是否可行为什么?
不可行如果在头文件中定义静态变量会造成资源浪费的问题同时也可能引起程序错误。因为如果在使用了该头文件的每个C语言文件中定义静态变量按照编译的步骤
在每个头文件中都会单独存在一个静态变量从而会引起空间浪费或者程序错误所以不推荐在头文件中定义任何变量当然也包括静态变量。