2014-01-21 2 views
1

Как это сделать на C++?Как я могу объявить неизменный класс в C++ (пример Java)

//java example 
public class MyImmutable { 
    private final int numToBeInitializedOnConstructionOrCompilationError; 

    public MyImmutable(int n) { 
     this.numToBeInitializedOnConstructionOrCompilationError = n; 
    } 
} 

С Java, если окончательное свойство не инициализируется при объявлении или на конструктор, компилятор выдаст ошибку, этот код работает, так как переменная-член инициализируется в конструкторе. Как я могу обеспечить неизменность в объявлении класса в C++?

(определение только публичных методов геттер не является приемлемым ответом, я знаю, «сопзЬ» должен быть частью решения)

Если я это сделать в C++:

class MyImmutable 
{ 
    private: 
    const int numToBeInitializedOnConstruction; 

    public: 
    MyImmutable(int n); 
}; 

MyImmutable::MyImmutable(int n) 
{ 
    numToBeInitializedOnConstruction = n; 
} 

я получаю следующее ошибки, в основном говорят мне, что я не могу назначить член const, поэтому я думаю, что const более строгий, чем «final» java, есть ли другое ключевое слово или есть способ инициализировать const после того, как он был объявлен?

$ gcc const.cc 
const.cc:10:10: error: constructor for 'MyClass' must explicitly initialize the const member 
     'numToBeInitializedOnConstruction' 
MyClass::MyClass(int n) { 
     ^
const.cc:3:13: note: declared here 
    const int numToBeInitializedOnConstruction; 
      ^
const.cc:11:36: error: read-only variable is not assignable 
    numToBeInitializedOnConstruction = n; 
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
2 errors generated. 

так как я могу объявить эквивалент конечной переменной-члена java в C++? Это возможно?

ответ

11

C++ может обрабатывать неизменность объекта гораздо лучше, чем на Java. Прежде всего, вы можете сделать неизменный объект из почти любого типа с квалификатором const.

const string str = "asd"; 
const MyClass myObj(1); 

Вы также можете иметь постоянные атрибуты, как этот numToBeInitializedOnConstruction у вас есть, но он должен быть инициализирован в списке инициализации членов конструктора, например:

MyImmutable::MyImmutable(int n) 
: numToBeInitializedOnConstruction(n) // like this 
{ 
} 
+0

спасибо так много, что это именно то, что мне нужно :) – Gubatron

2

Используйте список инициализации, как:

MyImmutable::MyImmutable(int n): numToBeInitializedOnConstruction(n) {}

EDIT: Только лучше отступа.

2

Чтобы объявить неизменный объект, просто объявим его как const:

const Foo myImmutableFoo; 

Чтобы объявить неизменные атрибуты класса, вы можете объявить этих членов const - но вы не использовали правильный синтаксис для их инициализации. Дано:

class Foo 
{ 
    const int mImmutableN; 
public: 
    Foo(); 
}; 

Вы не можете инициализировать mImmutableN в теле конструктора; он должен быть инициализирован в списке инициализации конструктора:

Foo::Foo() 
: 
    mImmutableFoo (42) 
{ 
} 
+0

Как это отличается от поста сделал 14 минут назад? – Reimeus

+0

@Reimeus: В основном это не так. Когда я начал писать, ответа не было. Независимо от того, некоторые будущие читатели могут найти мое объяснение легче переварить, чем те, которые уже были предоставлены. С другой стороны, они не могут; ничего страшного. Нет вреда в нескольких ответах, которые дают одну и ту же информацию по-разному. –

Смежные вопросы