第一篇:默认拷贝构造函数
拷贝构造函数剖析
在讲课过程中,我发现大部分学生对拷贝构造函数的理解不够深入,不明白自定义拷贝构造函数的必要性。因此,我将这部分内容,进行了总结。
拷贝构造函数是一种特殊的构造函数,其形参为本类的对象引用。功能:使用一个已经存在的对象始初化同类的一个新对象。这样得到对象和原来的对象具有完全相同的数据成员,即相同的属性。
拷贝构造函数的函数原型:
A ( const A& other) { … … }
拷贝构造函数的应用场合:
当用类的一个对象去初始化该类的另一个对象时;若函数的形参为类对象,调用函数时,实参赋值给形参;当函数的返回值是类对象时。比如:
A a1(10);
A a2 = a1;
A a3(a1);// 构造函数 // 拷贝构造函数 // 拷贝构造函数
默认拷贝构造函数:成员变量之间的“值”拷贝
编写拷贝构造函数的必要性
class A
{
public:
A(const char* data)
{
name = new char[strlen(data) + 1];
strcpy (name, data);
}
A(const A& other)
{
name = new char[strlen(other.name) + 1];
strcpy(name, other.name);
}
private:
char* name;
};
考察:char* data = “abcd”;A a1(data);A a2 = a1;
如果未定义拷贝构造函数,会有何种后果?
现将a1赋给a2,缺省拷贝构造函数的“位拷贝”意味着执行a2.name = a1.name。这将造成二个错误:一是a2.name和a1.name指向同一块内存,任何一方变动都会影响另一方;二是在对象被析构时,name被释放了两次。
第二篇:偷懒的办法处理拷贝构造函数与赋值函数
如果我们实在不想编写拷贝构造函数和赋值函数,又不允许别人使用编译器生成的缺省函数,怎么办?
偷懒的办法是:只需将拷贝构造函数和赋值函数声明为私有函数,不用编写代码。 例如:
class A
{ …
private:
A(const A &a);// 私有的拷贝构造函数
A & operate =(const A &a); // 私有的赋值函数
};
如果有人试图编写如下程序:
Ab(a); // 调用了私有的拷贝构造函数
b = a;// 调用了私有的赋值函数
编译器将指出错误,因为外界不可以操作A的私有函数。
第三篇:C#方法重载、构造函数、重载构造函数小结
方法重载
可以使同一功能适用于各种类型的数据,它是声明两个以上的同名方法,实现对不同数据类型进行相同的处理 方法重载的要求
1、
重载的方法名称必须相同
2、
重载的方法,其形参个数或类型必须不同
如我们定义了swap(ref int a,ref intb)该函数用来实现两个整形变量值的交换,但不会处理浮点型数据,我们在定义一个swap(ref flot a,ref flot b),这样swap这个方法可以实现整形变量值的交换,也可以实现浮点型数据交换了(系统会根据数据的类型自己决定调用合适的方法) 构造函数
主要作用是在创建对象(声明对象)时初始化对象。一个类定义必须至少有一个构造函数,如果定义类时,没有声明构造函数,系统会提供一个默认的构造函数。举个例子或许可以更好的理解它: 结果是:
若想在创建对象时,将对象数据成员设定为指定的值,则要专门声明构造函数。 声明构造函数的要求:
1、
构造函数不允许有返回类型
2、
构造函数名称必须与类同名。
通常构造函数是为了在创建对象时对数据成员初始化,所以构造函数需要使用形参。 public Student(string ID,int Age) {
id=ID;
age=Age; } 由于上述构造函数带了参数,系统不会提供默认构造函数,所以在创建对象时,必须按照声明的构造函数的参数要求给出实际参数。
Student s1= new Student(“90090”,22); New关键字后面实际是对构造函数的调用。
如果声明构造函数时使用的参数名称和类数据成员名称相同,那么构造函数中使用的类数据成员名称要有this引导 Public student(string id,int age) {
This.id=id;
This.age=age; } 关键字this指的是创建的对象,是声明对象时,由系统自动传递给构造函数的对象的引用形参。 重载构造函数
构造函数和方法一样都可以重载。重载构造函数的主要目的是为了给创建对象提供更大的灵活性,以满足创建对象时的不同需要。
如上面的例子,如果只想改变age则重载构造函数Student只需要有一个参数age就可以了。 虚方法
声明与基类同名的派生类方法 Public new 方法名称(参数列表){} 声明虚方法
基类中声明格式
Publicvirtual方法名称(参数列表){}
派生类中声明格式
Publicoverride方法名称(参数列表){}
调用基类方法
在派生类中声明一基类同名的方法,也叫方法重载。在派生类重载基类方法后,如果像调用基类的同名方法,使用base关键字。
声明抽象类和抽象方法 Public abstractclasse 类名称 {public abstract 返回类型方法名称(参数列表);} 重载抽象方法
Public override 返回类型 方法名称(参数列表)
第四篇:构造函数
1.设
f(x)
,g(x)分别为定义在R上的奇函数和偶函数,当x0时,
f(x)g(x)f(x)g(x)0,且g(3)0,则不等式f(x)g(x)0的解集为______.
2.设f(x)是定义在R上的奇函数,且f(2)0,当x0时,有x
f(x)f(x)0
恒成立,则不等式x2f(x)0的解集为__________.
3.已知函数f(x)是定义在R上的奇函数,且当x(,0)时,有x<0成立,若a30.3
b
f(x)+f(x)1
3f(3
0.3
)
,blog3
f(log
3),c(log
3
9
)f(log
9
),则a、
、c的大小关系为__________.
f(x),则当a0
4.已知可导函数f(x)满足f(x)系为__________.
时,f(a)与ea
f(0)
的大小关
5.若函数f(x)对任意的xR都有f(x)
A.3f(ln2)2f(ln3)
f(x)
成立,则__________.B.3f(ln2)2f(ln3)
C.3f(ln2)2f(ln3) D.3f(ln2)与2f(ln3)的大小关系不确定
6.设f(x)是R上的奇函数,且f(1)0,当x0时,(x2
1)f(x)2xf(x)0
,
则不等式f(x)0的解集为__________.
7.已知函数f(x)是定义在(0,)的非负可导函数,且满足x对任意正数a、b,若a
A.af(b)bf(a)
f(x)+f(x)0,
B.af(b)bf(a)C.af(a)f(b)
D.bf(b)f(a)
,
8.已知f(x)与g(x)都是定义在R上的函数,g(x)0,f(x)g(x)
f(x)ag(x),
x
f(x)g(x)0
f(1)g(1)
f(1)g(1)
52
.在有穷数列
f(n)
(n1,2,,10)中,前kg(n)
项和
为
1516
,则k=__________.
第五篇:类的构造函数 析构函数与赋值函数
构造函数 析构函数与赋值函数是每个类最基本的函数。它们太普通以致让人容易麻痹大意,其实这些貌似简单的函数就象没有顶盖的下水道那样危险。
每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数)。对于任意一个类A,如果不想编写上述函数,C++编译器将自动为A产生四个缺省的函数,如
A(void);// 缺省的无参数构造函数
A(const A &a);// 缺省的拷贝构造函数
~A(void);// 缺省的析构函数
A & operate =(const A &a); // 缺省的赋值函数
这不禁让人疑惑,既然能自动生成函数,为什么还要程序员编写?
原因如下:
(1)如果使用“缺省的无参数构造函数”和“缺省的析构函数”,等于放弃了自主“初始化”和“清除”的机会,C++发明人Stroustrup的好心好意白费了。
(2)“缺省的拷贝构造函数”和“缺省的赋值函数”均采用“位拷贝”而非“值拷贝”的方式来实现,倘若类中含有指针变量,这两个函数注定将出错。
对于那些没有吃够苦头的C++程序员,如果他说编写构造函数 析构函数与赋值函数很容易,可以不用动脑筋,表明他的认识还比较肤浅,水平有待于提高。
本章以类String的设计与实现为例,深入阐述被很多教科书忽视了的道理。String的结构如下:
class String
{
public:
String(const char *str = NULL); // 普通构造函数
String(const String &other); // 拷贝构造函数
~ String(void);// 析构函数
String & operate =(const String &other); // 赋值函数private:
char*m_data;// 用于保存字符串
};