本文转载自:点击打开链接
一,
C ++中的结构对象的结构进行了扩充,它已经不再只是一个包含不同数据类型的数据结构了,它已经获得了太多的功能。
结构能包含成员函数吗?能!
结构能继承吗?能!
结构能实现多态吗?能!
最本质的一个区别就是默认的访问控制,体现在两个方面:
1)默认的继承访问权限.struct是公共的,类是私有的。
写如下的代码:
结构一
{
char a;
};
结构B:甲
{
char b;
};
这个时候乙是公共继承一个的如果都将上面的结构改成类,那么乙是私有继承一个的这就是默认的继承访问权限所以我们在平时写类继承的时候,通常会这样写:
结构B:公共甲
就是为了指明是公共继承,而不是用默认的私有继承。
当然,到底默认是公共继承还是私有继承,取决于子类而不是基类。我的意思是,结构可以继承类,同样的类也可以继承结构,那么默认的继承访问权限是看子类到底是用的结构还是类如下:
struct A {};
B类:A {}; //私有继承
结构C:B {}; //公共继承
2)结构作为数据结构的实现体,它默认的数据访问控制是公开的,而类作为对象的实现体,它默认的成员变量访问控制是私人的。
3)“类”这个关键字还用于定义模板参数,就像“类型名称”。但关键字“结构”不用于定义模板参数。
4)还是上面所说的,C ++中的结构是对C中的结构的扩展,既然是扩充,那么它就要兼容过去C结构应有的所有特性。例如你可以这样写:
struct A //定义一个结构体
{
char c1;
int n2;
双DB3;
};
A = {'p',7,3.1415926}; //定义时直接赋值
也就是说结构可以在定义的时候用{}赋初值。
向上面的结构中加入一个构造函数(或虚函数),结构也不能用{}赋初值了。的确,以{}的方式来赋初值,只是用一个初始化列表来对数据进行按顺序的初始化,如上面如果写成A a = {'p',7};则c1,n2 was初始化,而db3没有。这样简单的复制操作,只能发生在简单的数据结构上,而不应该放在对象上。加入一个构造函数或是一个虚函数会使结构更体现出一种对象的特性,而使此{}操作不再有效。事实上,是因为加入这样的函数,使得类的内部结构发生了变化。而加入一个普通的成员函数呢?你会发现{}依旧可用。其实你可以将普通的函数理解成对数据结构的一种算法,这并不打破它数据结构的特性。至于虚函数和普通成员函数有什么区别,我会具体写篇文章讨论。
那么,看到这里,我们发现即使是结构想用{}来赋初值,它也必须满足很多的约束条件,这些条件实际上就是让结构更体现出一种数据机构而不是类的特性。那为什么我们在上面仅仅将结构改成类,{}就不能用了呢其实问题恰巧是我们之前所讲的 - ?!?访问控制你看看,我们忘记了什么对,将结构改成类的时候,访问控制由公立变为私有了,那当然就不能用{}来赋初值了。加上一个公共的,你会发现,类也是能用{}的,和结构毫无区别!
从上面的区别,我们可以看出,结构更适合看成是一个数据结构的实现体,类更适合看成是一个对象的实现体。
二,
关于使用大括号初始化
类和结构如果定义了构造函数的话,都不能用大括号进行初始化
如果没有定义构造函数,结构可以用大括号初始化。
如果没有定义构造函数,且所有成员变量全是公开的话,可以用大括号初始化。
关于默认访问权限
类中默认的成员访问权限是私有的,而结构中则是公开的。
关于继承方式
的类继承默认是私有继承,而结构继承默认是公共继承。
且看如下代码(看看编译器给出的错误信息):
class T1
{
public:
void f()
{
cout <<“T1 :: f()”<< endl;
}
int x,y;
};
struct T2
{
int x;
void f(){cout <<“T2 :: f()”<< endl;}
};
struct TT1:T1
{
};
class TT2:T2
{
};
int main()
{
TT1 t1;
TT2 t2;
t1.f();
t2.f();
}
关于模版
在模版中,类型参数前面可以使用类或类型名,如果使用结构,则含义不同,结构后面跟的是“非类型模板参数”,而类或类型名称后面跟的是类型参数。
template <struct X>
void f(X x)
{
}
//出错信息:d:codecpptestcpptestcpptest.cpp(33):error C2065:'X':未声明的标识符