目录
概念
继承和组合是两种表达对象之间关系的方式:
1、继承表示“是一个”,
2、组合表示“有一个”。
例如,一只鸟可以继承“动物”这个类,因为它是动物的一种;
又例如,一台电脑由主板、CPU、内存等组成,每个部件都是电脑的一部分,因此使用组合来表示它们之间的关系。在具体的程序设计中,需要根据实际需要来选择使用哪种方式。
区别
两者的区别在于,继承是基于类之间的继承关系,是静态的,在编译时确定;
而组合是基于对象之间的组合关系,是动态的,在运行时确定。
另外,继承会导致代码的耦合度增高,而组合则不会。在设计程序时,应该根据具体需求来选择使用哪一种关系。
MyString:
#include <cstring>
#include <iostream>
class String
{
public:
String() : size_(0), data_(new char[1]) { *data_ = '\0'; } // 默认构造函数
String(const char* str); // 带C风格字符串参数的构造函数
String(const String& str); // 拷贝构造函数
~String() { delete[] data_; } // 析构函数
String& operator=(const String& rhs); // 拷贝赋值函数
const char* c_str() const { return data_; } // 返回C风格字符串
size_t size() const { return size_; } // 返回字符串长度
bool empty() const { return (size_ == 0); } // 判断字符串是否为空
String& operator+=(const String& rhs); // 字符串连接
char operator[](size_t index) const { return data_[index]; } // 重载下标运算符
private:
size_t size_;
char* data_;
};
String::String(const char* str) : size_(strlen(str)), data_(new char[size_ + 1])
{
strcpy(data_, str);
}
String::String(const String& str) : size_(str.size_), data_(new char[size_ + 1])
{
strcpy(data_, str.data_);
}
String& String::operator=(const String& rhs)
{
if (this == &rhs)
{
return *this;
}
delete[] data_;
size_ = rhs.size_;
data_ = new char[size_ + 1];
strcpy(data_, rhs.data_);
return *this;
}
String& String::operator+=(const String& rhs)
{
size_t rhs_size = rhs.size_;
char* new_data = new char[size_ + rhs_size + 1];
strcpy(new_data, data_);
strcpy(new_data + size_, rhs.data_);
delete[] data_;
data_ = new_data;
size_ += rhs_size;
return *this;
}
std::ostream& operator<<(std::ostream& os, const String& str) // 重载输出运算符
{
os << str.c_str();
return os;
}
int main()
{
String s1; // 默认构造函数
std::cout << "s1: " << s1 << ", size: " << s1.size() << ", empty: " << s1.empty() << std::endl;
String s2("Hello"); // 带C风格字符串参数的构造函数
std::cout << "s2: " << s2 << ", size: " << s2.size() << ", empty: " << s2.empty() << std::endl;
String s3 = s2; // 拷贝构造函数
std::cout << "s3: " << s3 << ", size: " << s3.size() << ", empty: " << s3.empty() << std::endl;
String s4;
s4 = s3; // 拷贝赋值函数
std::cout << "s4: " << s4 << ", size: " << s4.size() << ", empty: " << s4.empty() << std::endl;
s2 += " world!"; // 字符串连接
std::cout << "s2: " << s2 << ", size: " << s2.size() << ", empty: " << s2.empty() << std::endl;
std::cout << "s2[1]: " << s2[1] << std::endl; // 重载下标运算符
return 0;
}