void ClientCode(const Creator& creator) { // ... std::cout << "Client: I'm not aware of the creator's class, but it still works.\n" << creator.SomeOperation() << std::endl; // ... }
时间: 2024-04-18 14:31:28 浏览: 85
这段代码定义了一个名为 "ClientCode" 的函数,它接受一个 "Creator" 类型的参数 "creator"。在函数中,我们可以看到以下几个步骤:
1. 输出一条消息,表示客户端并不知道具体的创建者类,但仍然可以正常工作。
2. 调用 "creator" 对象的 "SomeOperation" 成员函数,并将其返回值输出到标准输出流。
这个代码片段展示了一种松耦合的设计模式,称为依赖倒置原则(Dependency Inversion Principle)。根据该原则,高层模块不应该依赖于低层模块的具体实现,而是应该依赖于抽象。
在这里,客户端代码并不关心具体的创建者类,它只知道创建者类是基于抽象类 "Creator" 的。通过接受 "Creator" 对象作为参数,客户端代码可以调用抽象类中定义的操作,而无需知道具体的实现。
这种设计模式可以提高代码的可维护性和可扩展性。如果需要添加新的创建者类,客户端代码不需要进行修改,只需要传递相应的创建者对象即可。这符合开闭原则(Open-Closed Principle),即对扩展开放,对修改封闭。
相关问题
template<typename T> void log(const T& t) { std::cout << t; } template<typename ...T> void log(const T&... data) { std::cout << data...; } template<typename ...T> void infof(const T& ...data) { std::cout << "\033[32;1m"; log(data...); std::cout << "\033[0m" << std::endl; }以上代码编译报错为“Def.h: In function ‘void log(const T& ...)’: Def.h:13:19: error: expected ‘;’ before ‘...’ token std::cout << data...; ^~~ Def.h:13:12: error: parameter packs not expanded with ‘...’: std::cout << data...; ~~~~^”,什么原因?怎么解决?
这个错误是因为在函数模板`log`的可变参数模板中,`data`参数没有被展开。正确的写法应该是使用展开运算符`...`,如下所示:
```
template<typename ...T> void log(const T&... data) {
(std::cout << ... << data);
}
```
这个函数模板可以展开多个参数,并通过`...`展开运算符将这些参数连接到一起,然后输出到标准输出流中。在函数模板`infof`中调用`log`函数时,也应该使用展开运算符`...`,如下所示:
```
template<typename ...T> void infof(const T& ...data) {
std::cout << "\033[32;1m";
log(data...);
std::cout << "\033[0m" << std::endl;
}
```
这个函数先输出一个绿色的提示信息,并调用函数模板`log`来输出参数。最后输出一个换行符,表示输出结束。
#include <iostream> #include <string> class Person { protected: std::string name; int age; std::string addr; public: void get_value() { std::cout << "请输入姓名:"; std::cin >> name; std::cout << "请输入年龄:"; std::cin >> age; std::cout << "请输入地址:"; std::cin >> addr; } }; class Teacher : public Person { public: void display() { std::cout << "姓名:" << name << std::endl; std::cout << "年龄:" << age << std::endl; std::cout << "地址:" << addr << std::endl; std::cout << "我是教师" << std::endl; } }; class Student : public Person { public: void display() { std::cout << "姓名:" << name << std::endl; std::cout << "年龄:" << age << std::endl; std::cout << "地址:" << addr << std::endl; std::cout << "我是学生" << std::endl; } }; int main() { Teacher t; Student s; s.get_value(); t = s; t.display(); return 0; }并重载operator=
在上面的代码基础上,我们可以为Teacher类重载operator=,使得可以直接将一个Student对象赋值给Teacher对象。代码如下:
```cpp
#include <iostream>
#include <string>
class Person {
protected:
std::string name;
int age;
std::string addr;
public:
void get_value() {
std::cout << "请输入姓名:";
std::cin >> name;
std::cout << "请输入年龄:";
std::cin >> age;
std::cout << "请输入地址:";
std::cin >> addr;
}
};
class Teacher : public Person {
public:
void display() {
std::cout << "姓名:" << name << std::endl;
std::cout << "年龄:" << age << std::endl;
std::cout << "地址:" << addr << std::endl;
std::cout << "我是教师" << std::endl;
}
Teacher& operator=(const Student& s) {
this->name = s.name;
this->age = s.age;
this->addr = s.addr;
return *this;
}
};
class Student : public Person {
public:
void display() {
std::cout << "姓名:" << name << std::endl;
std::cout << "年龄:" << age << std::endl;
std::cout << "地址:" << addr << std::endl;
std::cout << "我是学生" << std::endl;
}
};
int main() {
Teacher t;
Student s;
s.get_value();
t = s;
t.display();
return 0;
}
```
在Teacher类中,我们重载了operator=,使得可以将一个Student对象s赋值给Teacher对象t。在重载函数中,我们将s的数据成员name、age和addr分别赋值给t的对应成员,并返回一个指向t的引用。在主程序中,我们可以看到,我们仍然先创建了Teacher和Student对象t和s,然后调用s的get_value()函数获取数据,接着将s赋值给t,最后调用t的display()函数输出数据。
阅读全文