【设计模式专题之建造者模式】4. 自行车加工

注意重载<<函数的写法和使用方式,使用时与其它重载符号区别于参数对象。
另外定义为 friend 该类的友元函数意味着其可以访问该类的私有成员,而不加friend 则operator<< 被定义为全局函数,而不是类的成员函数。这意味着这个函数不能直接访问类的私有成员,因为它不是类的成员函数。

#include <iostream>
#include <bits/stdc++.h>

using namespace std;

class Bike{
private:
    string frame;
    string tires;
    
public:
    void setFrame(const string& frame){
        this->frame = frame;
    }
    void setTires(const string& tires){
        this->tires = tires;
    }
    friend ostream& operator<<(ostream& os, const Bike& bike){
        os << bike.frame << " " << bike.tires;
        return os;
    }
};

class BikeBuilder{
public:
    virtual void buildFrame() = 0;
    virtual void buildTires() = 0;
    virtual Bike getResult() = 0;
};

class MountainBikeBuilder : public BikeBuilder{
private:
    Bike bike;

public:
    void buildFrame() override{
        bike.setFrame("Aluminum Frame");
    }
    void buildTires() override{
        bike.setTires("Knobby Tires");
    }
    Bike getResult() override{
        return bike;
    }
};

class RoadBikeBuilder : public BikeBuilder{
private:
    Bike bike;

public:
    void buildFrame() override{
        bike.setFrame("Carbon Frame");
    }
    void buildTires() override{
        bike.setTires("Slim Tires");
    }
    Bike getResult() override{
        return bike;
    }
};

class BikeDirector{
public:
    Bike construct(BikeBuilder& builder){
        builder.buildFrame();
        builder.buildTires();
        return builder.getResult();
    }    
};

int main(){
    int N;
    cin >> N;
    
    BikeDirector director;
    
    for (int i = 0; i < N; i++){
        BikeBuilder* builder = nullptr;
        string type;
        cin >> type;
        if (type == "mountain"){
            builder = new MountainBikeBuilder();
        }else if (type == "road"){
            builder = new RoadBikeBuilder();
        }
        Bike bike = director.construct(*builder);
        cout << bike << endl;
        
        delete builder;
    }
    return 0;
}

【设计模式专题之原型模式】5. 矩形原型

注意两点:

  1. 在未显示定义拷贝构造函数时,C++编译器会使用默认拷贝构造函数,且是浅拷贝;创建新对象时使用 = 叫做 复制初始化,会调用拷贝构造函数。

拷贝构造函数用于创建一个对象的副本,它在以下情况下被调用:

对象通过值传递给函数。
对象以值传递方式从一个函数返回。
通过另一个对象初始化一个新对象。
当对象作为另一个对象的元素被初始化时

浅拷贝指的是新对象复制了原对象成员变量的指针,与原对象共享动态分配的内存块;深拷贝指的是复制了原对象的所有成员,包括指向的动态分配的内存,每个成员都有自己的内存副本(新对象不改变成员变量的值时,新对象与原对象指向同一块内存,改动新对象成员变量值时, 新对象成员变量指针发生变动,指向自己的副本内存并对值进行改动,记得是这样)

  1. RectanglePrototype类中return 后使用的 + 是string类重载的 +。
#include<iostream>
#include<bits/stdc++.h>
using namespace std;

class Prototype{
public:
    virtual Prototype* clone() = 0;
    virtual string getDetails() = 0;
};

class RectanglePrototype : public Prototype{
private:
    string color;
    int width;
    int height;
public:
    RectanglePrototype(string color, int width, int height): color(color), width(width), height(height) {}

    Prototype* clone() override{
        return new RectanglePrototype(*this); // 使用编译器默认拷贝构造函数
    }
    string getDetails() override{
        return "Color: " + color + ", Width: " + to_string(width) + ", Height: " + to_string(height); // string类重载的加号
    }
};

int main(){
    vector<Prototype*> rectangles;
    
    int N;
    cin >> N;
    
    for (int i = 0; i < N; i++){
        string color;
        int width;
        int height;
        
        cin >> color >> width >> height;
        
        Prototype* originalPrototype = new RectanglePrototype(color, width, height);
        rectangles.push_back(originalPrototype);
    }
    for (const auto& rectangle : rectangles){
        Prototype* colneRectangle = rectangle->clone(); //复制初始化,编译器调用默认拷贝构造函数,浅拷贝
        cout << colneRectangle->getDetails() << endl;
        delete colneRectangle;
    }
    
    for (const auto& rectangle : rectangles){
        delete rectangle;
    }
    return 0;
}

设计模式第三天打卡,复习了很多C++面向对象的知识,对从前从视频上看到的知识理解更加深了哈哈哈,还是得自己动手敲代码学习理解的深啊,加油!!!

02-04 15:06