首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >比如C++设计模式来避免指针?

比如C++设计模式来避免指针?
EN

Stack Overflow用户
提问于 2011-02-05 03:43:50
回答 2查看 1K关注 0票数 2

我有一个类层次结构,如下面的示例所示,其中State包含一个ZipCode的列表和一个City的列表,每个列表都包含指向ZipCode的指针。

目标是能够更新ZipCode,而不需要更新City(或创建City的新实例)。

下面的C++代码满足了这个要求,但是它使用指针,因为thisthat,所以我更喜欢避免指针。,我怎样才能重新设计这个简单的实现,使它不依赖指针?,谢谢你的帮助!

编辑:下面更新的代码使用boost::shared_ptr而不是原始指针。请注意,StateCityZipCode只是示例名称,它们原来是糟糕的选择名称(我本可以选择"A“、"B”和"C"),因为实际的代码允许等效的City共享ZipCode的名称。

代码语言:javascript
复制
#include <iostream>
#include <vector>
#include <boost/shared_ptr.hpp>

using namespace std;

/**
 * Zone Improvement Plan (ZIP) code
 */
class ZipCode {
public:
    ZipCode() : code_(0), plus4_(0) {}
    ZipCode(int code, int plus4 = 0) : code_(code), plus4_(plus4) {}
    virtual ~ZipCode() {};

    int code() const { return code_; }
    int plus4() const { return plus4_; }
    void set_code(int code) { code_ = code; }
    void set_plus4(int plus4) { plus4_ = plus4; }

private:
    int code_;
    int plus4_;
};

typedef boost::shared_ptr<ZipCode> ZipPtr;

/**
 * City points to one or more zip codes
 */
class City {
public:
    const vector<ZipPtr>& zip() const { return zip_; }
    void add_zip_ptr(const ZipPtr x) { if (x != NULL) zip_.push_back(x); }

private:
    // TODO: this vector should be a hash set
    vector<ZipPtr> zip_;
};

/**
 * State contains cities, each of which has pointers to
 * zip codes within the state.
 */
class State {
public:
    const vector<City>& city() const { return city_; }
    const vector<ZipPtr>& zip() const { return zip_; }

    const ZipPtr zip_of(int code) const {
        for (size_t i = 0; i < zip_.size(); i++) {
            if (zip_[i]->code() == code) {
                return zip_[i];
            }
        }
        return ZipPtr();
    }

    void add_city(const City& x) { city_.push_back(x); }
    void add_zip(int code) { zip_.push_back(ZipPtr(new ZipCode(code))); }

private:
    // TODO: these vectors should be hash sets
    vector<City> city_;
    vector<ZipPtr> zip_;
};

int main() {
    State texas;
    City dallas, houston;

    // create state ZIPs
    texas.add_zip(75380);
    texas.add_zip(75381);
    texas.add_zip(77219);
    texas.add_zip(77220);

    // point city ZIPs to the ones we just created
    dallas.add_zip_ptr(texas.zip_of(75380));
    dallas.add_zip_ptr(texas.zip_of(75381));
    houston.add_zip_ptr(texas.zip_of(77219));
    houston.add_zip_ptr(texas.zip_of(77220));

    // print all ZIPs
    cout << "ZIPs in Texas: " << endl;
    const vector<ZipPtr>& zips = texas.zip();
    for (size_t i = 0; i < zips.size(); i++) {
        cout << "    " << zips[i]->code() << endl;
    }
    cout << "ZIPs in Dallas, Texas: " << endl;
    const vector<ZipPtr> zip_ptrs1 = dallas.zip();
    for (size_t i = 0; i < zip_ptrs1.size(); i++) {
        cout << "    " << zip_ptrs1[i]->code() << endl;
    }
    cout << "ZIPs in Houston, Texas: " << endl;
    const vector<ZipPtr> zip_ptrs2 = houston.zip();
    for (size_t i = 0; i < zip_ptrs2.size(); i++) {
        cout << "    " << zip_ptrs2[i]->code() << endl;
    }

    // change a state ZIP...
    cout << "Changing Houston's ZIP 77220..." << endl;
    ZipPtr z = texas.zip_of(77220);
    if (z != NULL) z->set_code(88888);

    // ...and show the ZIPs of the affected city
    cout << "ZIPs in Houston, Texas: " << endl;
    const vector<ZipPtr> zip_ptrs3 = houston.zip();
    for (size_t i = 0; i < zip_ptrs3.size(); i++) {
        cout << "    " << zip_ptrs3[i]->code() << endl;
    }

    return 0;
}
EN

回答 2

Stack Overflow用户

发布于 2011-02-05 05:46:49

我认为这种情况是两种1:n的关系

  1. State:== 1:n
  2. City : Zipcode == 1: n

基于此,我认为State包含

代码语言:javascript
复制
vector<ZipCode> zip_;

听起来不太好。

我可能会这么做

代码语言:javascript
复制
class State {
    vector< City > cities_in_state_;
};

class City {
    vector< Zipcode > zips_in_city_;
};

这不需要指针。

票数 1
EN

Stack Overflow用户

发布于 2011-02-05 04:10:54

除非您想复制您的ZipCode对象,否则就属于这类用法(在your first link中描述):

-- Bar实例实际上是由程序的其他部分管理的,而Foo类只需要能够访问它。

这似乎是合法使用。

但是,您可能需要考虑copy选项(如果向量必须重新分配其数据,就可以永久避免问题),或者让State从其Cities聚合ZipCodes,而不是分发ZipCodes

复制仅仅意味着停止在City中使用指针。聚合ZipCodes意味着不是给状态一个ZipCodes列表,而是给City一个ZipCode实例的列表,在调用zip_of时,您将遍历这些城市并遍历它们的ZipCode集合。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4904995

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档