当前位置:首页 > 开发 > 编程语言 > 编程 > 正文

细说构造函数中的常引用

发表于: 2010-04-25   作者:bardo   来源:转载   浏览次数:
摘要: 细说构造函数中的常引用 ( 2006-10-30 19:25 )     构造函数用于对象的初始化。这一点相信大都明白。但是:构造函数不能被继承,基类是要先初始化的,基类初始化工作如何做?     C++是通过代码调用,以实现基类初始化在派生类的前面,单一继承的语法如下:    <派生类名>::&
细说构造函数中的常引用 ( 2006-10-30 19:25 )

    构造函数用于对象的初始化。这一点相信大都明白。但是:构造函数不能被继承,基类是要先初始化的,基类初始化工作如何做?
    C++是通过代码调用,以实现基类初始化在派生类的前面,单一继承的语法如下:
   <派生类名>::<派生类名>(<参数表>):<基类名>::<基类名>(<参数表>)
{
<派生类成员的初始化代码>
}
也就是说:在派生类构造函数后面加上“:”,在后面列出要调用的基类的构造函数。
   如:CMyTrigon::CMyTrigon(int iheight,int iwidth) : CMyRect(iheight, iwidth)
   如果多继承,则加“,”再一一列出要调用的基类的构造函数。列出时要注意按派生的顺序。
    需要注意的是:
    派生类构造函数必须负责读取基类构造函数中所需的参数。如上例,int iheight,int iwidth是读取基类所要的参数。CMyRect(iheight, iwidth)是在派生类读到参数后,对基类派生类的调用。

    C++类的构造函数的参数与普通函数能数一样,同样也有三种形式:
1、实参,即通过值传递。
如:CTrigon(int nWidth,int nHeight)
2、形参,通过指针传递。
如:CRondInTrigon(const CRond *rond,int nWidth,int nHeight)
3、形参,通过引用传递。
如:CRondInTrigon(const CRond &rond,int nWidth,int nHeight)
    为什么要通过形参来传递呢?
    从上面代码就可以发现,当一个类中的成员是另一个类的对象,或者是结构等,我们就必须使用指针或引用。否则,我们没有其它办法传递该类参数。
    这里面有一个非常特别的问题,那就是,凡是通过引用或指针传递的,都需要用常指针或常引用来传。为什么?
    首先要了解,const是做什么用的?const是用来限定变量中的数据不可改变。但是对指针中的地址或引用中的地址无任何作用。也就是说:
    下面的函数将会出错:
void swap(const int *x, const int *y)
{
int tmp=*x;
*x=*y;
*y=tmp;
}
    同样,下列函数一样也会出错:
void swap(const int &x, const int &y)
{
int tmp=x;
x=y;
y=tmp;
}

    原因就在于,const是对数据进行保护,使其不可写。但是,如果我们改变其指针所指的变量,这种改变就不会出错。为什么?指针或引用主要依据地址,而地址是程序中的辅助数据。我们要保护的是数据不能改变。
    如,下面程序就不会出错。但是却有两个典型的错误:
    因为通过指针或引用,我们可以返回多个数据。但我们不能改变指针或引用。下例是要改变指针。则需要用指针的指针才行。同时,下例中返回局部指针也是不对的。因为局部指针在函数运行结束后将不存在。

#include
void nswap(const int *x, const int *y)
{
int m=12;
int n=13;
int *j=&m;
int *k=&n;
x=j;
y=k;
}

main()
{
int m=21;
int n=31;
int *x=&m;
int *y=&n;
nswap(x,y);
printf("%d;%d\n",*x,*y);
}

    那么,我们可以假设,对于传入对象的构造函数,不用const,结果会如何?
    幸运时,你不会出错。但是不幸情况很多。因为,你无法预料,在你的程序中何时改变参数的数值。这时,不想要的结果就出现了。尤其是在派生类的复杂构造函数。
像:CRondInTrigon(const CRond *rond,int nWidth,int nHeight)
这个构造函数,你总不想要,初始化了rond,再构造CRondInTrigon后,发现,你在rond的初始化数据已不是原来的数据吧?有const就会有写保护而及时指出你的错!
    有人说,派生函数中的参数,最好加上const,实际上这种说法是不对的!
    C++还有一种特殊的构造函数,那就是为自己建一副本的构造函数——拷贝构造函数。原因是因为:已有一个在使用的对象,现在要用这个对象的数据重新构造一个新对象。如果将原对象中的数据取出来,则需要调用其中的相关成员函数才行。用拷贝构造函数可以复制指定对象的数据到本对象。
    下面就是一个实例:
//注意:此类不是MFC的CRECT,而是自定义类
CMyRect(const CmyRect &rt) {
    If  (&rt !=this)   //如果rt不是我,这是条件,不能自我复制。
//(这也算是this的一个用法)
{
            //复制成员
            height= rt.GetHeight();
            width= rt.GetWidth();
            left=rt.nleft;
     top= rt.ntop;
}
        }

    在此类构造函数中,一样需要用const进行限定,因为,你只要复制,并不想改变你原有的对象的数据。
    总之,如果你是用指针虞引用传入构造函数,你需要加上const以保护传入的数据。
    当然,需要补充的是,常引用可以使参数有默认值,这也是非常有用的:
像以下代码:
const int &m=2;
编译器先将2赋给临时变量。然后再引用临时变量
即:
int tmp=2;
const int &m=tmp;
由此,我们可以用在函数中,而不是这样写程序,因为这样是没有必要的。下面是样例程序:
#include
int nswap(int &x,const int &y=3)
{

int k=y;
x+=2;
k+=5;
return(x*k);

}

void main()
{
int m=2;
int n=1;
int t=nswap(m,n);
printf("%d;%d;%d\n",t,m,n);
int p=nswap(m);
printf("%d;%d;%d\n",p,m,n);

}
也就是说,以引用传参,是可以有默认值的。要做到有默认值,必须要用常引用才行!

细说构造函数中的常引用

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
  今天想做道矩阵的题目时,却卡在一些编程细节上了,找了好久才发现原来是在构造函数处出了问题
/* *Copyright (c)2014,烟台大学计算机与控制工程学院 *All rights reserved. *文件名称:d.cpp *作
前面有一篇文章讲了指针与引用。并且还提到不能定义指向引用的指针(因为引用不是对象,没有实际的地
构造函数---KVC构造函数 /** 构造函数 - 建立一个`对象` 1. 给属性分配空间 2. 设置初始数值 Swift
由架构中基类的设计想到的...... 现在,有三个类,类的定义如下 #include <iostream> using n
构造函数、析构函数与拷贝构造函数介绍 2.1构造函数 构造函数不能有返回值 缺省构造函数时,系统将
一、构造函数初始化列表 推荐在构造函数初始化列表中进行初始化 构造函数的执行分为两个阶段 初始化
构造函数主要是用来创建对象时为对象赋初值来初始化对象。总与new运算符一起使用在创建对象的语句中
  static以前都接触过,可是最近才发现了还有静态类的写法,也可能是以前没太注意了,所以自己去
用wpf一段时间了,里面有许多东西还是和winform有许多不同的,其中有一点需要注意的就是: 不要在wp
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号