C++拷贝构造函数

C++拷贝构造函数

关键字:   C++

默认拷贝构造函数的行为如下:

默认的拷贝构造函数执行的顺序与其他用户定义的构造函数相同,执行先父类后子类的构造.

拷贝构造函数对类中每一个数据成员执行成员拷贝(memberwise Copy)的动作.

a)如果数据成员为某一个类的实例,那么调用此类的拷贝构造函数.

b)如果数据成员是一个数组,对数组的每一个执行按位拷贝.

c)如果数据成员是一个数量,如int,double,那么调用系统内建的赋值运算符对其进行赋值.

1.深拷与浅拷

深拷贝和浅拷贝的定义可以简单理解成:如果一个类拥有资源(堆,或者是其它系统资源),当这个类的对象发生复制过程的时候(复制指针所指向的值),这个过程就可以叫做深拷贝,反之对象存在资源但复制过程并未复制资源(只复制了指针所指的地址)的情况视为浅拷贝。

浅拷贝资源后在释放资源的时候会产生资源归属不清的情况导致程序运行出错,这点尤其需要注意!

原则上,应该为所有包含动态分配成员的类都提供拷贝构造函数。

浅:

using namespace std;

//shallow && deep copy

//deep copy make pointer point to a new place!

class Product

...{

public:int* pointer;

Product(int i=0)

...{

pointer=new int(i);

}

//change class variable

void change(int i)

...{

*pointer=i;

}

//deconstructor

~Product()

...{

delete pointer;

}

};

int main()

...{

Product p1(2);

Product p2(p1);

p1.change(3);

cout

getchar();

return 0;

}

深:

using namespace std;

//shallow && deep copy

//deep copy make pointer point to a new place!

class Product

...{

public:int* pointer;

Product(int i=0)

...{

pointer=new int(i);

}

//change class variable

void change(int i)

...{

*pointer=i;

}

// copying constructor

Product(const Product &p)

...{

pointer=new int(*p.pointer);

}

//deconstructor

~Product()

...{

delete pointer;

}

};

int main()

...{

Product p1(2);

Product p2(p1);

p1.change(3);

cout

getchar();

return 0;

}

2 拷贝构造函数的另一种调用

当对象直接作为参数传给函数时,函数将建立对象的临时拷贝,这个拷贝过程也将调用拷贝构造函数。

例如:

#include

using namespace std;

class Date...{

int n;

public:

Date(int i = 0)

...{

cout

n = i;

}

Date(const Date &d)

...{

cout

n = d.n;

}

int GetMember()

...{

return n;

}

};

void Display(Date obj) //针对obj的操作实际上是针对复制后的临时拷贝进行的

...{

cout

}

int main()

...{

Date a;

Date b(99);

Display(a);  //对象直接作为参数

Display(b);  //对象直接作为参数

getchar();

return 0;

}

程序输出:

载入构造函数:

载入构造函数:

载入拷贝构造函数

0载入拷贝构造函数

99

还有一种情况,也是与临时对象有关的。

当函数中的局部对象被用作返回值,返回给函数调用时,也将建立此局部对象的一个临时拷贝,此时拷贝构造函数也将被调用。——可是经测试发现情况有异。

代码如下:

#include

using namespace std;

class Date...{

int n;

public:

Date(int i = 0)

...{

cout

n = i;

}

Date(const Date &d)

...{

cout

n = d.n;

}

void Show()

...{

cout

}

};

Date GetClass(void)  //函数中的局部对象被用作返回值,按理说应该引用拷贝构造函数

...{

Date temp(100);

return temp;

}

int main()

...{

Date a;

a.Show();

a = GetClass();//这里GetClass()函数中的局部对象被用作返回值

a.Show();

Date b = GetClass();//这里GetClass()函数中的局部对象被用作返回值

b.Show();

getchar();

return 0;

}

程序输出:

载入构造函数:

n = 0

载入构造函数:

n = 100

载入构造函数:

n = 100

按理第2个和第3个应该输出'载入拷贝构造函数"才对,这个结果与预想的不一样,到底是哪里出问题了呢?

注:后来有论坛上的朋友告诉我说这是因为编译器的不同而导致不同的输出。

有人得到这样的输出结果:

载入构造函数

n = 0

载入构造函数

载入拷贝构造函数

n = 100

载入构造函数

载入拷贝构造函数

n = 100

还有人得到这样的输出结果:

载入构造函数

n = 0

载入构造函数

载入拷贝构造函数

n = 100

载入构造函数

载入拷贝构造函数

载入拷贝构造函数

n = 100

(用的是vc++)

3.3 无名对象

现在我们来说一下无名对象。什么是无名对象?利用无名对象初始化对象系统不会调用拷贝构造函数?这是我们需要回答的两个问题。

首先我们来回答第一个问题。很简单,如果在程序的main函数中有:

Internet ("中国");  //Internet表示一个类

这样的一句语句就会产生一个无名对象。

无名对象会调用构造函数,但利用无名对象初始化对象时系统不会调用拷贝构造函数!

下面的代码是常见的利用无名对象初始化对象的例子。

#include

using namespace std;

class Date...{

int n;

public:

Date(int i = 0)

...{

cout

n = i;

}

Date(const Date &d)

...{

cout

n = d.n;

}

void Show()

...{

cout

}

};

int main()

...{

Date a(100);

a.Show();

Date b = a;  //"="在对象声明语句中,表示初始化,调用拷贝构造函数

b.Show();

Date c;

c.Show();

c = a;  //"="在赋值语句中,表示赋值操作,调用赋值函数

c.Show();

getchar();

return 0;

}

程序输出:

载入构造函数:

name的地址:  23ff40;name的字符串:  中国

cname的地址:  33778;cname的字符串:  中国

载入析构函数:

上面代码的运行结果有点“出人意料”,从思维逻辑上说,当无名对象创建了后,是应该调用自定义拷贝构造函数,或者是默认拷贝构造函数来完成复制过程的,但事实上系统并没有这么做,因为无名对象使用过后在整个程序中就失去了作用。对于这种情况c++会把代码看成是: Internet a ("中国");  省略了创建无名对象这一过程,所以说不会调用拷贝构造函数。

3.赋值符的重载

由于并非所有的对象都会使用拷贝构造函数和赋值函数,程序员可能对这两个函数有些轻视。请先记住以下的警告,在阅读正文时就会多心:

本章开头讲过,如果不主动编写拷贝构造函数和赋值函数,编译器将以“位拷贝”的方式自动生成缺省的函数。倘若类中含有指针变量,那么这两个缺省的函数就隐含了错误。以类String的两个对象a,b为例,假设a.m_data的内容为“hello”,b.m_data的内容为“world”。

现将a赋给b,缺省赋值函数的“位拷贝”意味着执行b.m_data = a.m_data。这将造成三个错误:一是b.m_data原有的内存没被释放,造成内存泄露;二是b.m_data和a.m_data指向同一块内存,a或b任何一方变动都会影响另一方;三是在对象被析构时,m_data被释放了两次。

拷贝构造函数和赋值函数非常容易混淆,常导致错写、错用。拷贝构造函数是在对象被创建时调用的,而赋值函数只能被已经存在了的对象调用。以下程序中,第三个语句和第四个语句很相似,你分得清楚哪个调用了拷贝构造函数,哪个调用了赋值函数吗?

String  a(“hello”);

String  b(“world”);

String  c = a; // 调用了拷贝构造函数,最好写成 c(a);

c = b;  // 调用了赋值函数

本例中第三个语句的风格较差,宜改写成String c(a) 以区别于第四个语句。

请看下面的代码:

(1) 没有重载赋值函数

#include "stdafx.h"

using namespace std;

//shallow && deep copy

//deep copy make pointer point to a new place!

class Product

...{

public:int* pointer;

Product(int i=0)

...{

pointer=new int(i);

}

//change class variable

void change(int i)

...{

*pointer=i;

}

// copying constructor

Product(const Product &p)

...{

pointer=new int(*p.pointer);

}

//deconstructor

~Product()

...{

delete pointer;

}

};

int main()

...{

Product p1(1);

Product p2(2);

Product p3(3);

p2=p3;

p3.change(4);

cout

getchar();

return 0;

}

//结果输出4

(2)重载赋值函数

#include "stdafx.h"

using namespace std;

//shallow && deep copy

//deep copy make pointer point to a new place!

class Product

...{

public:int* pointer;

Product(int i=0)

...{

pointer=new int(i);

}

//change class variable

void change(int i)

...{

*pointer=i;

}

// copying constructor

Product(const Product &p)

...{

pointer=new int(*p.pointer);

}

//重载=

Product& operator=(const Product &p)

...{

if(this!=&p)

pointer=new int(*p.pointer);

return *this;

}

//deconstructor

~Product()

...{

delete pointer;

}

};

int main()

...{

Product p1(1);

Product p2(2);

Product p3(3);

p2=p3;

p3.change(4);

cout

getchar();

return 0;

}

//输出3

5. 在拷贝构造函数中使用赋值函数

为了简化程序,我们通常在拷贝构造函数中使用赋值函数。

例如:

#include

using namespace std;

class Date...{

int da, mo, yr;

public:

Date(int d = 0, int m = 0, int y = 0)

...{

cout

da = d;

mo = m;

yr = y;

}

Date(const Date &other);

Date & operator =(const Date &other);

void Show()

...{

cout

}

};

Date::Date(const Date &other) //拷贝构造函数中使用赋值函数

...{

cout

*this = other;

}

Date & Date::operator =(const Date &other)

...{

cout

if(this == &other)

return *this;

da = other.da;

mo = other.mo;

yr = other.yr;

return *this;

}

int main()

...{

Date a(1, 3, 6);

a.Show();

Date b = a;

b.Show();

Date c;

c.Show();

c = a;

c.Show();

getchar();

return 0;

}

程序输出:

载入构造函数:

3-1-6

载入拷贝构造函数

载入赋值函数

3-1-6

载入构造函数:

0-0-0

载入赋值函数

3-1-6

请注意:程序输出了两次“载入赋值函数”,这是因为我们在拷贝构造函数中使用了赋值函数,这样使程序变得简洁。如果把拷贝构造函数改写为:

Date::Date(const Date &other)

{

cout

da = other.da;

mo = other.mo;

yr = other.yr;

}

则程序将输出:

载入构造函数:

3-1-6

载入拷贝构造函数

3-1-6

载入构造函数:

0-0-0

载入赋值函数

3-1-6

6. 偷懒的办法处理拷贝构造函数和赋值函数

如果我们实在不想编写拷贝构造函数和赋值函数,又不允许别人使用编译器生成的缺省函数,怎么办?

偷懒的办法是:只需将拷贝构造函数和赋值函数声明为私有函数,不用编写代码。

例如:

class A

{ …

private:

A(const A &a);    // 私有的拷贝构造函数

A & operator =(const A &a); // 私有的赋值函数

};

如果有人试图编写如下程序:

A  b(a); // 调用了私有的拷贝构造函数

b = a;  // 调用了私有的赋值函数

编译器将指出错误,因为外界不可以操作A的私有函数。(引自〈〈高质量c++编程指南〉〉)

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1666934

C++拷贝构造函数

关键字:   C++

默认拷贝构造函数的行为如下:

默认的拷贝构造函数执行的顺序与其他用户定义的构造函数相同,执行先父类后子类的构造.

拷贝构造函数对类中每一个数据成员执行成员拷贝(memberwise Copy)的动作.

a)如果数据成员为某一个类的实例,那么调用此类的拷贝构造函数.

b)如果数据成员是一个数组,对数组的每一个执行按位拷贝.

c)如果数据成员是一个数量,如int,double,那么调用系统内建的赋值运算符对其进行赋值.

1.深拷与浅拷

深拷贝和浅拷贝的定义可以简单理解成:如果一个类拥有资源(堆,或者是其它系统资源),当这个类的对象发生复制过程的时候(复制指针所指向的值),这个过程就可以叫做深拷贝,反之对象存在资源但复制过程并未复制资源(只复制了指针所指的地址)的情况视为浅拷贝。

浅拷贝资源后在释放资源的时候会产生资源归属不清的情况导致程序运行出错,这点尤其需要注意!

原则上,应该为所有包含动态分配成员的类都提供拷贝构造函数。

浅:

using namespace std;

//shallow && deep copy

//deep copy make pointer point to a new place!

class Product

...{

public:int* pointer;

Product(int i=0)

...{

pointer=new int(i);

}

//change class variable

void change(int i)

...{

*pointer=i;

}

//deconstructor

~Product()

...{

delete pointer;

}

};

int main()

...{

Product p1(2);

Product p2(p1);

p1.change(3);

cout

getchar();

return 0;

}

深:

using namespace std;

//shallow && deep copy

//deep copy make pointer point to a new place!

class Product

...{

public:int* pointer;

Product(int i=0)

...{

pointer=new int(i);

}

//change class variable

void change(int i)

...{

*pointer=i;

}

// copying constructor

Product(const Product &p)

...{

pointer=new int(*p.pointer);

}

//deconstructor

~Product()

...{

delete pointer;

}

};

int main()

...{

Product p1(2);

Product p2(p1);

p1.change(3);

cout

getchar();

return 0;

}

2 拷贝构造函数的另一种调用

当对象直接作为参数传给函数时,函数将建立对象的临时拷贝,这个拷贝过程也将调用拷贝构造函数。

例如:

#include

using namespace std;

class Date...{

int n;

public:

Date(int i = 0)

...{

cout

n = i;

}

Date(const Date &d)

...{

cout

n = d.n;

}

int GetMember()

...{

return n;

}

};

void Display(Date obj) //针对obj的操作实际上是针对复制后的临时拷贝进行的

...{

cout

}

int main()

...{

Date a;

Date b(99);

Display(a);  //对象直接作为参数

Display(b);  //对象直接作为参数

getchar();

return 0;

}

程序输出:

载入构造函数:

载入构造函数:

载入拷贝构造函数

0载入拷贝构造函数

99

还有一种情况,也是与临时对象有关的。

当函数中的局部对象被用作返回值,返回给函数调用时,也将建立此局部对象的一个临时拷贝,此时拷贝构造函数也将被调用。——可是经测试发现情况有异。

代码如下:

#include

using namespace std;

class Date...{

int n;

public:

Date(int i = 0)

...{

cout

n = i;

}

Date(const Date &d)

...{

cout

n = d.n;

}

void Show()

...{

cout

}

};

Date GetClass(void)  //函数中的局部对象被用作返回值,按理说应该引用拷贝构造函数

...{

Date temp(100);

return temp;

}

int main()

...{

Date a;

a.Show();

a = GetClass();//这里GetClass()函数中的局部对象被用作返回值

a.Show();

Date b = GetClass();//这里GetClass()函数中的局部对象被用作返回值

b.Show();

getchar();

return 0;

}

程序输出:

载入构造函数:

n = 0

载入构造函数:

n = 100

载入构造函数:

n = 100

按理第2个和第3个应该输出'载入拷贝构造函数"才对,这个结果与预想的不一样,到底是哪里出问题了呢?

注:后来有论坛上的朋友告诉我说这是因为编译器的不同而导致不同的输出。

有人得到这样的输出结果:

载入构造函数

n = 0

载入构造函数

载入拷贝构造函数

n = 100

载入构造函数

载入拷贝构造函数

n = 100

还有人得到这样的输出结果:

载入构造函数

n = 0

载入构造函数

载入拷贝构造函数

n = 100

载入构造函数

载入拷贝构造函数

载入拷贝构造函数

n = 100

(用的是vc++)

3.3 无名对象

现在我们来说一下无名对象。什么是无名对象?利用无名对象初始化对象系统不会调用拷贝构造函数?这是我们需要回答的两个问题。

首先我们来回答第一个问题。很简单,如果在程序的main函数中有:

Internet ("中国");  //Internet表示一个类

这样的一句语句就会产生一个无名对象。

无名对象会调用构造函数,但利用无名对象初始化对象时系统不会调用拷贝构造函数!

下面的代码是常见的利用无名对象初始化对象的例子。

#include

using namespace std;

class Date...{

int n;

public:

Date(int i = 0)

...{

cout

n = i;

}

Date(const Date &d)

...{

cout

n = d.n;

}

void Show()

...{

cout

}

};

int main()

...{

Date a(100);

a.Show();

Date b = a;  //"="在对象声明语句中,表示初始化,调用拷贝构造函数

b.Show();

Date c;

c.Show();

c = a;  //"="在赋值语句中,表示赋值操作,调用赋值函数

c.Show();

getchar();

return 0;

}

程序输出:

载入构造函数:

name的地址:  23ff40;name的字符串:  中国

cname的地址:  33778;cname的字符串:  中国

载入析构函数:

上面代码的运行结果有点“出人意料”,从思维逻辑上说,当无名对象创建了后,是应该调用自定义拷贝构造函数,或者是默认拷贝构造函数来完成复制过程的,但事实上系统并没有这么做,因为无名对象使用过后在整个程序中就失去了作用。对于这种情况c++会把代码看成是: Internet a ("中国");  省略了创建无名对象这一过程,所以说不会调用拷贝构造函数。

3.赋值符的重载

由于并非所有的对象都会使用拷贝构造函数和赋值函数,程序员可能对这两个函数有些轻视。请先记住以下的警告,在阅读正文时就会多心:

本章开头讲过,如果不主动编写拷贝构造函数和赋值函数,编译器将以“位拷贝”的方式自动生成缺省的函数。倘若类中含有指针变量,那么这两个缺省的函数就隐含了错误。以类String的两个对象a,b为例,假设a.m_data的内容为“hello”,b.m_data的内容为“world”。

现将a赋给b,缺省赋值函数的“位拷贝”意味着执行b.m_data = a.m_data。这将造成三个错误:一是b.m_data原有的内存没被释放,造成内存泄露;二是b.m_data和a.m_data指向同一块内存,a或b任何一方变动都会影响另一方;三是在对象被析构时,m_data被释放了两次。

拷贝构造函数和赋值函数非常容易混淆,常导致错写、错用。拷贝构造函数是在对象被创建时调用的,而赋值函数只能被已经存在了的对象调用。以下程序中,第三个语句和第四个语句很相似,你分得清楚哪个调用了拷贝构造函数,哪个调用了赋值函数吗?

String  a(“hello”);

String  b(“world”);

String  c = a; // 调用了拷贝构造函数,最好写成 c(a);

c = b;  // 调用了赋值函数

本例中第三个语句的风格较差,宜改写成String c(a) 以区别于第四个语句。

请看下面的代码:

(1) 没有重载赋值函数

#include "stdafx.h"

using namespace std;

//shallow && deep copy

//deep copy make pointer point to a new place!

class Product

...{

public:int* pointer;

Product(int i=0)

...{

pointer=new int(i);

}

//change class variable

void change(int i)

...{

*pointer=i;

}

// copying constructor

Product(const Product &p)

...{

pointer=new int(*p.pointer);

}

//deconstructor

~Product()

...{

delete pointer;

}

};

int main()

...{

Product p1(1);

Product p2(2);

Product p3(3);

p2=p3;

p3.change(4);

cout

getchar();

return 0;

}

//结果输出4

(2)重载赋值函数

#include "stdafx.h"

using namespace std;

//shallow && deep copy

//deep copy make pointer point to a new place!

class Product

...{

public:int* pointer;

Product(int i=0)

...{

pointer=new int(i);

}

//change class variable

void change(int i)

...{

*pointer=i;

}

// copying constructor

Product(const Product &p)

...{

pointer=new int(*p.pointer);

}

//重载=

Product& operator=(const Product &p)

...{

if(this!=&p)

pointer=new int(*p.pointer);

return *this;

}

//deconstructor

~Product()

...{

delete pointer;

}

};

int main()

...{

Product p1(1);

Product p2(2);

Product p3(3);

p2=p3;

p3.change(4);

cout

getchar();

return 0;

}

//输出3

5. 在拷贝构造函数中使用赋值函数

为了简化程序,我们通常在拷贝构造函数中使用赋值函数。

例如:

#include

using namespace std;

class Date...{

int da, mo, yr;

public:

Date(int d = 0, int m = 0, int y = 0)

...{

cout

da = d;

mo = m;

yr = y;

}

Date(const Date &other);

Date & operator =(const Date &other);

void Show()

...{

cout

}

};

Date::Date(const Date &other) //拷贝构造函数中使用赋值函数

...{

cout

*this = other;

}

Date & Date::operator =(const Date &other)

...{

cout

if(this == &other)

return *this;

da = other.da;

mo = other.mo;

yr = other.yr;

return *this;

}

int main()

...{

Date a(1, 3, 6);

a.Show();

Date b = a;

b.Show();

Date c;

c.Show();

c = a;

c.Show();

getchar();

return 0;

}

程序输出:

载入构造函数:

3-1-6

载入拷贝构造函数

载入赋值函数

3-1-6

载入构造函数:

0-0-0

载入赋值函数

3-1-6

请注意:程序输出了两次“载入赋值函数”,这是因为我们在拷贝构造函数中使用了赋值函数,这样使程序变得简洁。如果把拷贝构造函数改写为:

Date::Date(const Date &other)

{

cout

da = other.da;

mo = other.mo;

yr = other.yr;

}

则程序将输出:

载入构造函数:

3-1-6

载入拷贝构造函数

3-1-6

载入构造函数:

0-0-0

载入赋值函数

3-1-6

6. 偷懒的办法处理拷贝构造函数和赋值函数

如果我们实在不想编写拷贝构造函数和赋值函数,又不允许别人使用编译器生成的缺省函数,怎么办?

偷懒的办法是:只需将拷贝构造函数和赋值函数声明为私有函数,不用编写代码。

例如:

class A

{ …

private:

A(const A &a);    // 私有的拷贝构造函数

A & operator =(const A &a); // 私有的赋值函数

};

如果有人试图编写如下程序:

A  b(a); // 调用了私有的拷贝构造函数

b = a;  // 调用了私有的赋值函数

编译器将指出错误,因为外界不可以操作A的私有函数。(引自〈〈高质量c++编程指南〉〉)

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1666934


相关内容

  • 南昌大学C++题库
  • 一.单项选择题 1. 在C++语言中,对函数参数默认值描述正确的是:( ) A) 函数参数的默认值只能设定一个 B) 一个函数的参数若有多个,则参数默认值的设定可以不连续 C) 函数参数必须设定默认值 D) 在设定了参数的默认值后,该参数后面定义的所有参数都必须设定默认值 2. 假定 AB 为一个类 ...

  • C++模拟题2答案
  • C++程序设计模拟试卷(二) 一.单项选择题(本大题共20小题,每小题1分,共20分) 在每小题列出的四个备选项中 只有一个是符合题目要求的,请将其代码填写在题后的括号内.错选.多选或未选均无 分. 1. 静态成员函数没有() A. 返回值 B. this 指针 C. 指针参数 D. 返回类型 答案 ...

  • C++面向对象程序设计考试试卷(详细讲解)
  • C++面向对象程序设计 考试试卷(详细讲解) 一. 单项选择题(共20题,每题1分,共20分) 1.下列关于C++标识符的命名不合法的是 C 与C#一样 A. Pad B. name_1 C. A#bc D. _a12 2.若有以下类型标识符定义: ( )D int x=2: char w='a': ...

  • 拷贝构造函数的参数类型必须是引用(转)
  • 在C++中, 构造函数,拷贝构造函数,析构函数和赋值函数(赋值运算符重载)是最基本不过的需要掌握的知识. 拷贝构造函数的参数为什么必须使用引用类型? 原因: 如果拷贝构造函数中的参数不是一个引用,即形如CClass(const CClass c_class),那么就相当于采用了传值的方式(pass- ...

  • C++模拟试卷(一)
  • C++程序设计模拟试卷(一) 一.单项选择题(本大题共20小题,每小题1分,共20分) 在每小题列出的四个备选项中 只有一个是符合题目要求的,请将其代码填写在题后的括号内.错选.多选或未选均无 分. 1. 编写C++程序一般需经过的几个步骤依次是() A. 编辑.调试.编译.连接 B. 编辑.编译. ...

  • C面试笔试题
  • C/C++ 笔试.面试题目(1) 1.求下面函数的返回值(微软) int func(x) { int countx = 0; while(x) { countx ++; x = x&(x-1); } return countx; } 假定x = 9999. 答案:8 思路:将x转化为2进制, ...

  • 华为c++面试题及答案
  • 华为面试题1 一.请填写BOOL , float, 指针变量 与"零值"比较的 if 语句.(10分) 请写出 BOOL flag 与"零值"比较的 if 语句.(3分) 标准答案: 请写出 float x 与"零值"比较的 if 语句.( ...

  • 有答案的模拟题
  • 一.名词解释(每题5分,共10分) 1. 对象(Object) 面向对象方法中的对象,是系统中用来描述客观事物的一个实体,它是用来构成系统的一个基本单位. 2. 继承(Inherit) 特殊类的对象拥有其一般类的全部属性与服务,称作特殊类对一般类的继承. 二.填空(每题2分,共20分) 1. C++ ...

  • c++单选题
  • 单选题 1.下列关于面向对象概念的描述中,错误的是( C ). A.面向对象方法比面向过程方法更加先进 B.面向对象方法中使用了一些面向过程方法中没有的概念 C.面向对象方法替代了结构化程序设计方法 D.面向对象程序设计方法要使用面向对象的程序设计语言 2.下列各种高级语言中,不是面向对象的程序设计 ...