【问题标题】:C++: Accessing a data member of an instance of class A (holding a list of class B objects) from a B objectC++:从 B 对象访问 A 类实例的数据成员(保存 B 类对象的列表)
【发布时间】:2011-11-24 13:23:21
【问题描述】:

考虑以下代码:

#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 实例都需要一组具有不同替换的Value 实例设置。

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

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

为什么上面的代码甚至可以工作? Holder::valuesToReplace_ 是私人的!这只是正常的 C++ 行为(因为无论如何如果不访问类的私有成员就无法获得该指针)?

【问题讨论】:

  • 这个助手类真的有必要吗?看起来你所做的一切可以概括为:int replace_maybe(int n) { auto it = m.find(n); return it != m.end() ? it-&gt;second : n; }

标签: c++ oop


【解决方案1】:

为什么上面的代码甚至可以工作? 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 访问器方法。

【讨论】:

    【解决方案2】:

    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_;
    };
    

    【讨论】:

      猜你喜欢
      • 2021-12-01
      • 2011-08-02
      • 1970-01-01
      • 2019-10-22
      • 2021-11-10
      • 2010-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多