C ++:从B对象访问类A实例的数据成员(保存B类对象的列表)

时间:2011-11-24 13:23:21

标签: c++ oop

请考虑以下代码:

#include <iostream>
#include <map>

class Value
{
    public:
        void set(const int intValue){ intValue_ = intValue; }
        int read() const { return intValue_; }
        void replaceIfInMap(){
            std::map<int,int>::iterator it;
            it = valuesToReplace_->find(intValue_);
            if(it != valuesToReplace_->end()){
                intValue_ = it->second;
            }
        }
        Value(std::map<int,int>* valuesToReplace) : valuesToReplace_(valuesToReplace){}
    private:
        std::map<int,int>* valuesToReplace_;
        int intValue_;
};

class Holder    {  
    public:
        void doStuffWithValues(){
            Value a(&valuesToReplace_), b(&valuesToReplace_), c(&valuesToReplace_);
            a.set(1); b.set(2); c.set(3);
            valuesToReplace[2]=5;
            a.replaceIfInMap(); b.replaceIfInMap(); c.replaceIfInMap();
            std::cout << "a: "  << a.read()
                      << " b: " << b.read() 
                      << " c: " << c.read() << std::endl;
        }
    private:
        std::map<int,int> valuesToReplace_;
};

int main()
{
    Holder holder;
    holder.doStuffWithValues();
}

我怎样才能以更方便(也更优雅)的方式访问valuesToReplace_成员?我曾考虑将地图存储为类Value的公共静态成员,但这会否认有Holder类的多个实例的可能性,因为每个Holder实例需要一组{{1}具有不同替换设置的实例。

全球地图将是一个更加丑陋的“解决方案”......

Value调用Value::read()并进行地图交互没有选项,因为此代码只是一种简化,而在实际代码中,Holder的每个实例的等价物都可以存储指向同一类的其他实例的指针,使上述方法过于复杂和笨重。

为什么上面的代码甚至可以工作? Value是私密的!这只是普通的C ++行为(因为无论如何都无法访问该类的私有成员而无法获得该指针)?

2 个答案:

答案 0 :(得分:0)

  

为什么上面的代码甚至可以工作? Holder :: valuesToReplace_是   私人!

它是私有的,所以Holder :: doStuffWithValues可以访问它,因为它是一个成员函数,没有错。

Value a(&valuesToReplace_), b(&valuesToReplace_), c(&valuesToReplace_);
            a.set(1); b.set(2); c.set(3);

在这里,你所有的Value对象都有valuesToReplace_指向同一个地图是你想要的吗?看起来很奇怪,我要么有一个静态映射(可以在赋值时复制)或者是一个智能指针来防止意外删除(但允许NULL值)。

  

我怎样才能更多地访问valuesToReplace_成员   方便(最好是更优雅)的方式?

您可以将其保密,并具有返回地图的开始/结束const_iterators的公共成员函数,或者不依赖于内部实现的setIntForInt / getIntForInt访问器方法。

答案 1 :(得分:0)

如何将对valuesToReplace地图的引用传递给replaceIfInMap方法?

class Value
{
    public:
        void set(const int intValue){ intValue_ = intValue; }
        int read() const { return intValue_; }

        void replaceIfInMap(std::map<int,int> const& valuesToReplace_){
            std::map<int,int>::const_iterator it;
            it = valuesToReplace_->find(intValue_);
            if(it != valuesToReplace_->end()){
                intValue_ = it->second;
            }
        }

        Value() {}
    private:
        int intValue_;
};

class Holder    {  
    public:
        void doStuffWithValues(){
            Value a, b, c;
            a.set(1); b.set(2); c.set(3);
            valuesToReplace_[2]=5;
            a.replaceIfInMap(valuesToReplace_);
            b.replaceIfInMap(valuesToReplace_);
            c.replaceIfInMap(valuesToReplace_);
            std::cout << "a: "  << a.read()
                      << " b: " << b.read() 
                      << " c: " << c.read() << std::endl;
        }
    private:
        std::map<int,int> valuesToReplace_;
};