C++基础知识巩固

来源:互联网 发布:津桥留学 知乎 编辑:程序博客网 时间:2024/06/07 08:51
看到有人贴出的代码找错,所以,借此复习巩固一下C++基础知识,有不对的地方请大家指出,谢谢

#include <iostream>
#include <assert.h>
using namespace std;
 
class BaseObject
{
public:
    BaseObject(){//自定义的无参构造函数,则系统就不会调用默认构造函数,
//切记构造函数不能为虚函数,析构函数可以。
        m_nCount = 0;
        m_pData = new int[100];//此处对成员变量动态分配内存,我也不太明白要不要检查是否new成功,
//暂且加一句断言吧!
assert(m_pData != NULL );//断言分配成功,当assert()括号中的表达式为假时,
//就会调用库函数abort()来终止程序。头文件#include <assert.h>
    }
 
    ~BaseObject(){//有的人说此处应该加上virsual,因为看类貌似是个基类,恐后边有继承。。这个,怎么说,
//有子类的话当然得加上,没有的话也就没有必要了,虚函数会增加开销的,要生成虚函数表   
   if (m_pData)//判断一下指针是否为空,本人觉得很有必要
             delete []m_pData;//delete的时候一定要看仔细了,m_pData是个数组指针,所以应该加上[]
     m_pData = NULL;//detele 完成后立即将指针指向空
}
    }
 
    BaseObject(const BaseObject& t)//拷贝构造函数,参数必须带有const性质,即参数不能改变
    {
           m_nCount = t.m_nCount;//对成员变量的拷贝,切记住是否有深拷贝,即成员变量是否有动态分配内存,
//有的话就必须有深拷贝,例如m_pData

//深拷贝资源
     m_pData = new int[100];//必须添加不然段错误
    if( m_pData != NULL)
  {
     memcpy(m_pData,t.m_pData,sizeof(int) * 100);
  }
    
    }

 // 拷贝构造完成后,良好的习惯是应该想着有赋值函数,即重载=号操作符BaseObject & operator = (const BaseObject &)
//,因为main里边没有用到,所以我写出来而已
BaseObject & operator = (const BaseObject & tt )
{
if ( this == &tt)
return *this ;
delete []m_pData; //删除原来的数据,新开一块内存
m_pData = new int[100];
if( m_pData != NULL)
{
memcpy(m_pData,tt.m_pData,sizeof(int) * 100);
}
return *this;
}

    int Squre(volatile int* p) //volatile 易失变量,提示编译器不对变量的读取进行优化,
//永远只从内存中读取数值,保护数据的稳定访问。
    {
        return *p * *p; //这里实现的是两个数相乘,首先,当遇到指针变量时,用之前先判断指针是否为空,然后再去使用,
//此处显然没有判断,并且没有考虑到相乘是否溢出
    }

//此函数改成下边这样较好
    long long Squre(volatile int* p)
    {
assert( p != NULL)
        return (*p)*(*p);
    }
 
    void ChangeData() const//const 函数,函数不允许对成员变量进行运算操作,只能去读取,不能改变值,
//像这样对成员变量进行加操作肯定编译通不过,所以,应该去掉!
改为  void ChangeData()
    {
        m_nCount++;
    }
 
private:
    int m_nCount;
    int* m_pData;
};
 
int main()
{
    BaseObject object1;//调用用户自定义的无参构造函数
    BaseObject object2 = object1;//调用的是拷贝构造函数,而不是赋值构造函数,切记是否有深拷贝

//    BaseObject object3;
//    object3 = object1;//如果是这种情况就调用赋值构造函数,即等号操作符重载函数
    return 0;
}

另外贴上String类:

已知String类定义如下:

class String

{

public:

String(const char *str = NULL); // 通用构造函数

String(const String &another); // 拷贝构造函数

~ String(); // 析构函数

String & operater =(const String &rhs); //赋值函数

private:

char *m_data; // 用于保存字符串

};

尝试写出类的成员函数实现。

答案:

String::String(const char *str)

{

if ( str == NULL ) //strlen在参数为NULL时会抛异常才会有这步判断

{

m_data = new char[1] ;

m_data[0] = '/0' ;

}

else

{

m_data = new char[strlen(str) + 1];

strcpy(m_data,str);

}

}

String::String(const String &another)

{

m_data = new char[strlen(another.m_data) + 1];

strcpy(m_data,other.m_data);

}

 

String& String::operator =(const String &rhs)

{

if ( this == &rhs)

return *this ;

delete []m_data; //删除原来的数据,新开一块内存

m_data = new char[strlen(rhs.m_data) + 1];

strcpy(m_data,rhs.m_data);

return *this ;

}

 

String::~String()

{

delete []m_data ;

}


0 0
原创粉丝点击