4

在下面的代码中,const一个对象的非方法调用const相同对象的一个​​方法,该方法返回一个const指向对象字段的指针,然后这个返回的指针被强制转换为一个非const版本——这是一种类似于这个答案:优雅的解决方案来复制,const 和 non-const,getter?[重复]。但是,由于我将指针放入复杂的数据结构中,我不确定它是否真的有效。会吗?

class Struct {
private:
    Field f, g;

    std::map<std::string, const FieldBase*> const_fields_t;
    std::map<std::string, FieldBase*> fields_t;

public:
    const_fields_t get_fields() const {
        return const_fields_t { { "f", &f }, { "g", &g } };
   }

   fields_t get_fields() {
        const Foo* = this;
        fields_t result;

        foreach(auto& v : const_this->get_fields()) {
            result[v->first] = const_cast<FieldBase*>(v->second);
        }
        return result;
   }
};
4

1 回答 1

1

Yes, (I cleaned up your code a bit):

#include <string>
#include <functional>
#include <iostream>
#include <map>
using namespace std;

class FieldBase {public: virtual string get_data() = 0; };
class Field : public FieldBase { public: string data; virtual string get_data() { return data; } };

class Struct {
public:
    Field f, g;

    typedef std::map<std::string, const FieldBase*> const_fields_t;
    typedef std::map<std::string, FieldBase*> fields_t;

public:
    const_fields_t get_fields() const {
        cout << "const get_fields() called" << endl;
        return const_fields_t { { "f", &f }, { "g", &g } };
   }

   fields_t get_fields() {
        cout << "non-const get_fields() called" << endl;
        auto const_this = static_cast<const Struct*>(this);
        fields_t result;

        for(auto& v : const_this->get_fields()) {
            result[v.first] = const_cast<FieldBase*>(v.second);
        }
        return result;
   }
};

int main ()
{
    Struct a;
    a.f.data = "Hello";
    a.g.data = "World";

    Struct::fields_t obj = a.get_fields();

    cout << obj["f"]->get_data() << endl;
    cout << obj["g"]->get_data() << endl;

}

Live example

You basically have the const function act like a gateway to get the values you need and then cast away the constness. That will also work for your purpose since the pointers are going to be de-consted and stored in the new map.

Keep in mind that there might probably be a better solution not involving all the above copying around.

于 2014-09-02T13:05:51.463 回答