最近在上面向对象设计与分析这门课,老师在讲C++的相关内容,之前本科也没有系统的学习过C++,所有有些概念很模糊,还有些跟Java混淆了,但因为上课和我的时间比较有限,所以学哪里记哪里,还是会有些琐碎,慢慢来吧,以后有时间再系统学习。
C++类的声明与实现
在C++中,类的声明与实现可以写在一起,也可以分开写,先写声明然后在写实现。
声明和实现一起写
class Complex {
private:
float real;
float image;
public:
//构造函数
Complex(float real = 0, float image = 0) {
this->real = real;
this->image = image;
}
~Complex() {}
//拷贝构造函数
Complex(const Complex& c) {
this->real = c.real;
this->image = c.image;
}
//运算符“+”重载函数
Complex operator +(const Complex& c) {
return Complex(this->real + c.real, this->image + c.image);
}
//运算符“=”重载函数
Complex operator = (const Complex & c){
this->real = c.real;
this->image = c.image;
return *this;
}
//运算符“==”重载函数
Complex operator ==(const Complex& c) {
return fabs(this->real - c.real) < FLT_EPSILON && fabs(this->image - c.image) < FLT_EPSILON;
}
//运算符“>”重载函数
bool operator >(const Complex& c) const{
if (this->real == c.real) {
return this->image > c.image;
}
else {
return this->real > c.real;
}
}
};
先声明,后实现
声明
#pragma once
#include<stdio.h>
//类的声明
class MyString {
private:
char* m_pData;
public:
//构造函数
MyString(const char* str = NULL);
//拷贝构造函数
MyString(const MyString& another);
//析构函数
~MyString();
//运算符“=”重载函数
MyString& operator =(const MyString& another);
//运算符“>”重载函数
bool operator >(const MyString& another);
};
实现
#include<stdio.h>
#include<string.h>
#include"MyString.h"
//类的实现
//构造函数实现
MyString::MyString(const char* str) {
if (str) {
int len = strlen(str);
m_pData = new char[len + 1];
//memcpy指定从内存地址中复制内容的长度
memcpy(m_pData, str, len + 1);
}
else {
m_pData = new char[1];
m_pData[0] = '\0';
}
}
//拷贝构造函数实现
MyString::MyString(const MyString& another) {
int len = strlen(another.m_pData);
this->m_pData = new char[len + 1];
strcpy_s(this->m_pData, len + 1, another.m_pData);
}
//析构函数
MyString::~MyString() {
if (this->m_pData) {
delete []m_pData;
m_pData = NULL;
}
}
//运算符“=”重载函数
MyString& MyString::operator =(const MyString& another) {
if (this == &another) return *this;
delete[]this->m_pData;
int len = strlen(another.m_pData);
this->m_pData = new char[len + 1];
strcpy_s(this->m_pData, len + 1, another.m_pData);
return *this;
}
//运算符“>”重载函数
bool MyString::operator >(const MyString& another) {
if (strcmp(this->m_pData, another.m_pData) > 0) {
return true;
}
return false;
}
拷贝构造函数
拷贝构造函数一般会在赋值时被赋值的对象还未创建时被调用,使用上面定义的类进行示例:
Complex c1 = Complex(a, b);
Complex c2 = c1;
在执行Complex c2 = c1时会调用拷贝构造函数,可以在构造对象的同时进行赋值。即传值调用拷贝构造函数。
const用法
一、局部变量
const int a=1;
int const a=1;
两种写法相同,表示变量a的值不能进行改变。
二、常量指针与指针常量
常量指针是指针指向的内容是常量,定义方式如下:
const int * p;
int const * p;
注:
- 常量指针不能通过这个指针改变指向变量的值,但可以通过其他引用改变指向变量的值。
- 常量指针指向的值不能改变,但常量指针可以指向其他地址。
指针常量是指针本身是个常量,不能指向其他地址。定义方式如下:
int *const p;
==注:==指针常量指向的地址不能改变,但指向地址中的值可以通过其他指向该地址的指针改变。
指向常量的常指针指针指向的的地址不能改变,并且不能通过该指针更改该地址存储的值。但可以通过其他指向该地址的指针改变值。
const int* const p;
三、修饰函数参数
const修饰函数参数也分为三种情况:
- 防止修改指针指向的内容
void StringCopy(char *strDestination, const char *strSource);
- 防止修改指针指向的地址
void swap ( int * const p1 , int * const p2 )
3.防止修改指针指向的地址和指向地址中的内容
void test(const int * const p1 , const int * const p2 )
四、修饰函数的返回值
如果给以指针传递方式的函数返回值加 const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。
const char * GetString(void);
const char *str = GetString();
五、修饰全局变量
使用全局变量时,我们应该尽量的使用const修饰符进行修饰,这样防止不必要的人为修改,使用的方法与局部变量是相同。
&-引用的用法
&相当于取别名,对引用的操作与对变量直接操作完全一样。用法如下:
void swap(int &p1, int &p2) //此处函数的形参p1, p2都是引用
{ int p; p=p1; p1=p2; p2=p; }
-
在引用的使用中,单纯给某个变量取个别名是毫无意义的,引用的目的主要用于在函数参数传递中,解决大块数据或对象的传递效率和空间不如意的问题。
-
用引用传递函数的参数,能保证参数传递中不产生副本,提高传递的效率,且通过const的使用,保证了引用传递的安全性。
-
引用与指针的区别是,指针通过某个指针变量指向一个对象后,对它所指向的变量间接操作。程序中使用指针,程序的可读性差;而引用本身就是目标变量的别名,对引用的操作就是对目标变量的操作。
-
使用引用的时机。流操作符<<和>>、赋值操作符=的返回值、拷贝构造函数的参数、赋值操作符=的参数、其它情况都推荐使用引用。