C++基础知识巩固

看到有人贴出的代码找错,所以,借此复习巩固一下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
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值