Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 通过C+处理序列+;类接口_C++_List_Interface_Sequence - Fatal编程技术网

C++ 通过C+处理序列+;类接口

C++ 通过C+处理序列+;类接口,c++,list,interface,sequence,C++,List,Interface,Sequence,假设我正在为一个类a编写一个接口,该接口保存一个类型为B的对象列表,我希望能够通过类a的接口操作该列表。我可以将add_B、remove_B等方法放在A的接口上,但这会导致大量代码重复(这种情况在我的程序中的许多类中都会发生),因此我宁愿返回对列表本身的引用。然而,这将破坏封装。 有没有一个标准的方法来处理这种情况?在我目前的发展中,我不得不面对同样的情况。我刚刚传递了对列表的引用。我认为除了你提到的两个,没有其他选择。也许您应该创建一个方法来操作整个列表(add_b,remove_b)和一个方

假设我正在为一个类a编写一个接口,该接口保存一个类型为B的对象列表,我希望能够通过类a的接口操作该列表。我可以将add_B、remove_B等方法放在A的接口上,但这会导致大量代码重复(这种情况在我的程序中的许多类中都会发生),因此我宁愿返回对列表本身的引用。然而,这将破坏封装。

有没有一个标准的方法来处理这种情况?

在我目前的发展中,我不得不面对同样的情况。我刚刚传递了对列表的引用。我认为除了你提到的两个,没有其他选择。也许您应该创建一个方法来操作整个列表(add_b,remove_b)和一个方法来获取对列表中单个项的引用以进行项操作


顺便说一句:如果你没有使用向量来处理对象B的列表,那么我建议你这样做。

没有足够的信息来给出详细的答案,但是从表面上看问题,我认为
AddX
/
RemoveX
如果您想要限制列表操作,或者在添加或删除元素时需要维护一些其他约束,那么界面就可以了

然而,如果您经常需要对另一个类的列表进行复杂的操作,那么它可能不属于那里

如果您只想删除重复,请使用一种mixin类:

template<class T>
class ListOf {
public:
    // Public interface only allows adding or removal.
    typedef boost::shared_ptr<T> Ptr;
    void Add(const Ptr &elem) {
        elems_.insert(elem);
    }
    void Remove(const Ptr &elem) {
        elems_.erase(elem);
    }
protected:
    // Subclass can access container reference.
    typedef std::set<Ptr> ElemSet;
    ElemSet& Elements() {
        return elems_;
    }
    const ElemSet& Elements() const {
        return elems_;
    }
private:
    ElemSet elems_;
};

class Foo : public Bar, public ListOf<Baz> {
    ...
};
模板
类列表{
公众:
//公共接口仅允许添加或删除。
typedef boost::shared_ptr ptr;
无效添加(常量Ptr&elem){
元素插入(元素);
}
无效删除(常数Ptr&elem){
元素擦除(elem);
}
受保护的:
//子类可以访问容器引用。
typedef std::set ElemSet;
元素集和元素(){
返回元素;
}
常量ElemSet&Elements()常量{
返回元素;
}
私人:
元素集元素;
};
Foo类:公共酒吧、公共列表{
...
};

以下代码基于代理设计模式。通过将接口委托给“代理”对象,它保留了封装并避免了“a”中庞大的接口

还要注意typedef如何允许将“list”更改为“vector”或其他任何内容

struct B{};

struct A{
    struct containerproxy{
        void Add(B *pb);
        void Remove(B *pb);
    };
    friend struct containerproxy;
    containerproxy &GetProxy(){return mlprx;}
    typedef containerproxy intf;
    ~A(){
        // Code to delete list elements and cleanup the list
    }
private:
    containerproxy mlprx;
    list<B*> mlp;
};

void A::containerproxy::Add(B *pb){ /*code to add pb to mlp*/}
void A::containerproxy::Remove(B *pb){/*code to remove pb from mlp*/}

int main(){
    A a;
    A::intf &r = a.GetProxy();

    B *p = new B;
    r.Add(p);
}
结构B{}; 结构A{ 结构容器代理{ 无效添加(B*pb); 脱空(B*pb); }; friend struct containerproxy; containerproxy&GetProxy(){return mlprx;} typedef containerproxy intf; ~A(){ //用于删除列表元素并清理列表的代码 } 私人: containerproxy mlprx; 名单mlp; }; void A::containerproxy::添加(B*pb){/*将pb添加到mlp的代码*/} void A::containerproxy::Remove(B*pb){/*从mlp中删除pb的代码*/} int main(){ A A; A::intf&r=A.GetProxy(); B*p=新的B; r、 加(p); }
std::list也不错。似乎大多数人都会跳转到向量:)@Merlyn,链表在大多数情况下通常更糟糕,因为大多数时候你处理的是一个由几个,最多十几个元素组成的列表,所以向量的插入/删除速度不是问题,而且它们的缓存命中率也要高得多,与链表不同,转发/执行适配器模式并不是真正不受欢迎的,代码复制是明智的。代码复制最糟糕的部分是当您有创建多个维护点的代码时,您可能会得到多个代码略有不同的副本。这种情况对于进行维护编程的人来说可能并不明显,这正是令人头痛的地方:)小心地在类A上提供有用的功能,避免转发列表的每个方法,除非这样做很有意义。我喜欢这种解决方案。不过,我会将代理实现为一个独立的类(因为我将在许多地方使用它)。谢谢