const
このような宣言の意味は何ですか?const
混乱します。
class foobar
{
public:
operator int () const;
const char* foo() const;
};
const
このような宣言の意味は何ですか?const
混乱します。
class foobar
{
public:
operator int () const;
const char* foo() const;
};
const
メソッドにキーワードを追加すると、this
ポインターは基本的にconst
オブジェクトへのポインターになるため、メンバー データを変更することはできません。( を使用しない限りmutable
、後で詳しく説明します)。
キーワードは関数シグネチャの一部です。const
これは、オブジェクトが の場合に呼び出されるメソッドとそうでない場合の 2 つの同様のメソッドを実装できることを意味しますconst
。
#include <iostream>
class MyClass
{
private:
int counter;
public:
void Foo()
{
std::cout << "Foo" << std::endl;
}
void Foo() const
{
std::cout << "Foo const" << std::endl;
}
};
int main()
{
MyClass cc;
const MyClass& ccc = cc;
cc.Foo();
ccc.Foo();
}
これは出力されます
Foo
Foo const
const
非 const メソッドでは、バージョンではできないインスタンス メンバーを変更できます。上記の例のメソッド宣言を以下のコードに変更すると、いくつかのエラーが発生します。
void Foo()
{
counter++; //this works
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++; //this will not compile
std::cout << "Foo const" << std::endl;
}
これは完全に正しいわけではありません。メンバーを としてマークしmutable
、const
メソッドでそれを変更できるからです。主に内部カウンターなどに使用されます。その解決策は、以下のコードです。
#include <iostream>
class MyClass
{
private:
mutable int counter;
public:
MyClass() : counter(0) {}
void Foo()
{
counter++;
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++; // This works because counter is `mutable`
std::cout << "Foo const" << std::endl;
}
int GetInvocations() const
{
return counter;
}
};
int main(void)
{
MyClass cc;
const MyClass& ccc = cc;
cc.Foo();
ccc.Foo();
std::cout << "Foo has been invoked " << ccc.GetInvocations() << " times" << std::endl;
}
出力する
Foo
Foo const
Foo has been invoked 2 times
constは、メソッドがクラスのメンバーを変更しないことを約束することを意味します。オブジェクト自体がマークされている場合でも、そのようにマークされているオブジェクトのメンバーを実行できますconst
。
const foobar fb;
fb.foo();
合法だろう。
C ++での「const」の使用はいくつですか?を参照してください。詳細については。
修飾子は、メソッドが。のconst
任意の値で呼び出すことができることを意味しますfoobar
。違いは、constオブジェクトでnon-constメソッドを呼び出すことを検討する場合に発生します。foobar
タイプに次の追加のメソッド宣言があるかどうかを検討してください。
class foobar {
...
const char* bar();
}
このメソッドbar()
は非constであり、non-const値からのみアクセスできます。
void func1(const foobar& fb1, foobar& fb2) {
const char* v1 = fb1.bar(); // won't compile
const char* v2 = fb2.bar(); // works
}
ただし、背後にある考え方const
は、クラスの内部状態を変更しないメソッドをマークすることです。これは強力な概念ですが、C++では実際には強制できません。それは保証というよりは約束です。そして、しばしば壊れて、簡単に壊れるもの。
foobar& fbNonConst = const_cast<foobar&>(fb1);
これらのconstは、メソッド'withconst'が内部データを変更した場合にコンパイラがエラーになることを意味します。
class A
{
public:
A():member_()
{
}
int hashGetter() const
{
state_ = 1;
return member_;
}
int goodGetter() const
{
return member_;
}
int getter() const
{
//member_ = 2; // error
return member_;
}
int badGetter()
{
return member_;
}
private:
mutable int state_;
int member_;
};
テスト
int main()
{
const A a1;
a1.badGetter(); // doesn't work
a1.goodGetter(); // works
a1.hashGetter(); // works
A a2;
a2.badGetter(); // works
a2.goodGetter(); // works
a2.hashGetter(); // works
}
詳細については、これをお読みください
ブレアの答えは的を射ている。
ただしmutable
、クラスのデータ メンバーに追加できる修飾子があることに注意してください。そのようにマークされたメンバーは、契約に違反することなくメソッドで変更できます。const
const
特定のメソッドが呼び出された回数をオブジェクトに記憶させたいが、そのメソッドの「論理的」定数には影響を与えない場合などに、これを使用することができます。
ここで const は、その関数ではどの変数の値も変更できないことを意味します
class Test{
private:
int a;
public:
void test()const{
a = 10;
}
};
この例のように、テスト関数で変数の値を変更しようとすると、エラーが発生します。
関数宣言で使用されるconstキーワードは、それがconst メンバー関数であり、オブジェクトのデータ メンバーを変更できないことを指定します。