C++基础知识巩固
来源:互联网 发布:津桥留学 知乎 编辑:程序博客网 时间:2024/06/07 08:51
#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);
}
}
{
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类定义如下:
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 ;
}
- C语言基础知识巩固
- 巩固shell基础知识
- C++基础知识巩固
- Android基础知识巩固
- java基础知识巩固
- 复习巩固java基础知识
- php基础知识巩固
- java基础知识巩固
- Java 基础知识巩固
- java 基础知识巩固(一)
- 网络编程基础知识巩固
- Java 基础知识巩固(一)
- 排序方法巩固(基础知识)
- Android笔记--JAVA基础知识巩固
- android基础知识巩固开篇介绍
- Java基础知识巩固(一)
- 基础知识巩固,JavaScript数组复习
- MySQL基础知识复习与巩固
- BUG:com.sun.xml.internal.ws.model.RuntimeModelerException: runtime modeler error
- 【Spring MVC】教程——使用拦截器实现权限控制
- 学习Java开源框架前你应该了解的
- JS中如何判断null、undefined与NaN
- UDP的sendto也是会阻塞的
- C++基础知识巩固
- interrupt()方法结束子线程
- Phonegap的deviceready事件
- Oracle 11gR2学习之二(创建数据库及OEM管理篇)
- Java编译期常量
- C#开源资源大汇总
- 支持iOS 7.1!苹果发布Xcode 5.1更新
- Linux中sed和awk的使用及其相关实例解析
- TWaver HTML5学习笔记 —— 选择隐藏网元