C ++:用const成员替换类数组的元素

时间:2013-10-04 16:55:40

标签: c++ arrays const

我正在尝试修改具有const成员的对象数组:

enum Bar {
    Baz,
    Qux,
    Quux
};

class Foo {
    public:
    Foo(Bar a, int b): a_(a), b_(b) {};

    private:
    const Bar a_;
    const int b_;
};

int main(int argc, char* argv[]) {
    Bar b[] = {
        Baz,
        Baz
    };

    // This works fine
    b[0] = Qux;

    Foo f[] = {
        Foo(Baz,42),
        Foo(Qux,32)
    };

    // This doesn't
    f[0] = Foo(Quux,3);

    return 0;
}

但是编译器不会让我:

$ make test
g++     test.cc   -o test
test.cc: In member function ‘Foo& Foo::operator=(const Foo&)’:
test.cc:7:7: error: non-static const member ‘const Bar Foo::a_’, can’t use default assignment operator
test.cc:7:7: error: non-static const member ‘const int Foo::b_’, can’t use default assignment operator
test.cc: In function ‘int main(int, char**)’:
test.cc:31:22: note: synthesised method ‘Foo& Foo::operator=(const Foo&)’ first required here 
make: *** [test] Error 1

我确信编译器有其原因,我很想知道为什么代码不起作用。

我还想知道如何对f数组进行预期的更改。

现在,以下是我的工作,但看起来错了:

#include <cstring>
#include <iostream>

enum Bar {
    Baz,
    Qux,
    Quux
};

class Foo {
    public:
    Foo(Bar a, int b): a_(a), b_(b) {};

    /*Foo &operator=(Foo const& f) {
     return f;
    }*/

    const Bar a_;
    const int b_;
};

int main(int argc, char* argv[]) {
    Bar b[] = {
        Baz,
        Baz
    };

    // This works fine
    b[0] = Qux;

    Foo f[] = {
        Foo(Baz,42),
        Foo(Qux,32)
    };

    // This doesn't
    //f[0] = Foo(Quux,3);

    // This does...
    Foo foo1(Quux, 344);
    memcpy(&f[0], &foo1, sizeof(foo1));

    std::cout << "Hi " << f[0].b_ <<"\n";
    return 0;
}

我很欣赏不涉及memcpy但仍以所需方式更改数组的解决方案。

2 个答案:

答案 0 :(得分:3)

阵列与它无关。

Foo a, b;
a = b;

也应该无法编译,因为编译器不知道如何分配给const的值。

答案 1 :(得分:1)

您无法更改const成员的值。但是f[0] = Foo(Quux,3);f[0].a_ = Quux; f[0].b_ = 3;之外什么都不做,因为它们都是const成员,所以无法编译。

你唯一能想到的就是使用指针,例如:

#include <memory>

int main(int argc, char* argv[]) {
    // ...
    std::unique_ptr<Foo> f[] = {
        std::unique_ptr<Foo>(new Foo(Baz, 42)),
        std::unique_ptr<Foo>(new Foo(Qux, 32))
    };

    f[0].reset(new Foo(Quux, 4));
}

如果使用gcc,则必须使用-std = cpp11标志。 unique_ptr在标题“memory”中定义。