从语法上,class和struct做类型定义时只有两点区别:
(一)默认继承权限。如果不明确指定,来自class的继承按照private继承处理,来自struct的继承按照public继承处理;
(二)成员的默认访问权限。class的成员默认是private权限,struct默认是public权限。
除了这两点,class和struct基本就是一个东西。语法上没有任何其它区别。
类中私有静态成员数据可以被类中公有静态成员函数访问。
初始化变量顺序是根据成员变量的声明顺序来执行的,
答案中m_i为随机值。
类中常量必须在构造函数的初始化列表里面初始化或者将变量设置为static
VC++6.0,在类中声明为static的变量只能在类外面进行赋值。变量初始化可以改成enum。
析构函数可以使内联函数
单个参数的构造函数如果不添加explicit关键字,会定义一个隐含的类型转换(从参数类型转换到自己);添加explicit关键词会消除这种隐形转换
String类的函数:
#include<stdio.h>
#include<string>
#include<iostream>
using namespace std;
class String
{
public:
String(const char *str = NULL); // 通用构造函数
String(const String &another); // 拷贝构造函数
~String(void); // 析构函数
String & operator = ( const String &spr); // 赋值函数
friend ostream & operator << (ostream& output, String & str); //重载输出符 “<<”
friend istream& operator >> (istream& input, String& str);//重载输入符 >>
private:
char *m_data; // 用于保存字符串
};
String::String(const char *str)
{
if(str == NULL)
{
m_data = new char[1];
*m_data = '\0';
}
else
{
int length = strlen(str);
m_data = new char[length + 1];
strcpy(m_data, str);
}
};
String::String(const String &anther)
{
int length = strlen(anther.m_data);
m_data = new char[length + 1];
strcpy(m_data, anther.m_data);
};
String::~String(void)
{
delete [] m_data;
};
String & String::operator = ( const String &spr)
{
if(&spr == this)
return *this;
delete [] m_data;
int length = strlen(spr.m_data);
m_data = new char[length + 1];
strcpy(m_data, spr.m_data);
return *this;
};
ostream & operator << (ostream& output, String & str)
{
cout<<str.m_data;
return output;
};
istream& operator >> (istream& input, String& str)
{
cin>>str.m_data;
return input;
}
虚函数就是允许被其子类重新定义的成员函数。类子类重新定父类虚函数的做法称为覆盖(override)。重载(=overroad)指允许存在多个同名函数,而这些函数的参数表不同。
多态与覆盖相关,当子类重新定义了父类的虚函数后,父类指针根据赋予他的不同的子类指针,动态地调用属于子类的该函数,这样的函数调用在编译期间是无法确定的,
封装可以隐藏实现的细节,使得代码模块化;继承可以扩展已存在的代码模块(类);都是为了代码重用。而多态是为了接口重用。
多态的本质就是将子类类型的指针赋值给父类类型的指针。
虚函数总是在派生类中被改写,这种改写叫做override。重写的函数有一致的参数表和返回值。
友元是定义在类外的普通函数,但它必须在类体内进行声明。友元可以访问私有成员。有缘的作用是提高程序运行效率。
下面程序中 VC++6.0输出的结果为;8 20 32
#include<iostream>
#include<memory.h>
#include<assert.h>
using namespace std;
class A
{
char k[3];
public:
virtual void aa();
};
class B : public virtual A
{
char j[3];
public:
virtual void bb();
};
class C : public virtual B
{
char i[3];
public:
virtual void cc();
};
char c[3];
int main(void)
{
cout<<"sizeof(A ): "<<sizeof(A)<<endl;
cout<<"sizeof(B ): "<<sizeof(B)<<endl;
cout<<"sizeof(C ): "<<sizeof(C)<<endl;
cout<<"sizeof(c[3] ): "<<sizeof(c)<<endl;
return 0;
}
虚拟继承是多重继承中特有的概念。虚拟继承是为解决多重继承而出现的。
虚函数指针和虚指针是一个虚函数的实现细节。带有虚函数的类中的每一个对象都有一个虚指针指向该类的虚函数表。
C++ 通过抽象类或者把构造函数声明为private来阻止一个类被实例化。
模板、类层次结构、强制类型检查等新特性,以及大量使用了这些新特性的C++模板、算法库都明显增加了C++编译器的负担。但是这些新技能在不增加程序执行效率的前提下,明显降低了程序员的工作量。
运行时开销:虚基类,虚函数,RTTI异常对象的析构和构造。
摘自: 《程序员面试宝典》