Bunun const
gibi deklarasyonlarda anlamı nedir ? const
Beni karıştırır.
class foobar
{
public:
operator int () const;
const char* foo() const;
};
Bunun const
gibi deklarasyonlarda anlamı nedir ? const
Beni karıştırır.
class foobar
{
public:
operator int () const;
const char* foo() const;
};
Yanıtlar:
const
Anahtar kelimeyi bir yönteme eklediğinizde, this
işaretçi esasen const
nesneye bir işaretçi olur ve bu nedenle üye verilerini değiştiremezsiniz. (Kullanmazsanız mutable
, daha sonra daha fazla).
const
Anahtar kelime, iki benzer yöntemler nesnedir çağrılan birini uygulamak anlamına gelir fonksiyonları imza parçasıdır const
ve olmayan birinin.
#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();
}
Bu çıktı
Foo
Foo const
Const olmayan yöntemde, const
sürümde yapamayacağınız örnek üyelerini değiştirebilirsiniz . Yukarıdaki örnekteki yöntem bildirimini aşağıdaki koda değiştirirseniz bazı hatalar alırsınız.
void Foo()
{
counter++; //this works
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++; //this will not compile
std::cout << "Foo const" << std::endl;
}
Bu tamamen doğru değildir, çünkü bir üyeyi olarak işaretleyebilirsiniz mutable
ve bir const
yöntem daha sonra bunu değiştirebilir. Daha çok dahili sayaçlar ve eşyalar için kullanılır. Bunun çözümü aşağıdaki kod olacaktır.
#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;
}
hangisi çıktı
Foo
Foo const
Foo has been invoked 2 times
Sabit, yöntemin sınıfın hiçbir üyesini değiştirmeyeceğine söz verdiği anlamına gelir. Nesnenin kendisi işaretlenmiş olsa bile, bu kadar işaretlenmiş nesnenin üyelerini yürütebilirsiniz const
:
const foobar fb;
fb.foo();
yasal olur.
Bkz . C ++ 'da “const” kullanımları kaç ve hangileri? daha fazla bilgi için.
const
Eleme aracı yöntemleri herhangi bir değer çağrılabilir foobar
. Fark, bir const nesnesinde const olmayan bir yöntem çağırmayı düşündüğünüzde ortaya çıkar. Türünüzde foobar
aşağıdaki ek yöntem bildirimi olup olmadığını göz önünde bulundurun :
class foobar {
...
const char* bar();
}
Yöntem bar()
sabit değildir ve yalnızca sabit olmayan değerlerden erişilebilir.
void func1(const foobar& fb1, foobar& fb2) {
const char* v1 = fb1.bar(); // won't compile
const char* v2 = fb2.bar(); // works
}
Ancak arkadaki fikir const
, sınıfın iç durumunu değiştirmeyecek yöntemleri işaretlemektir. Bu güçlü bir kavramdır, ancak aslında C ++ ile uygulanamaz. Bu bir garantiden çok bir vaattir. Ve genellikle kırılan ve kolayca kırılan bir tane.
foobar& fbNonConst = const_cast<foobar&>(fb1);
const
Gerçi buradaki fikir sınıfın iç durumunu değiştirmeyecek yöntemleri işaretlemektir " için teşekkürler . Aradığım şey gerçekten buydu.
const
mı gelir?
Bu sabit, 'const' yöntemi dahili verileri değiştirirse derleyicinin Hata vereceği anlamına gelir.
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_;
};
Test
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
}
Daha fazla bilgi için bunu okuyun
const
Üye işlevleriyle ilgili değişken olmayan bir soru en iyi ihtimalle eksiktir.
Blair'in cevabı işaret üzerindedir.
Ancak, mutable
sınıfın veri üyelerine eklenebilecek bir niteleyici olduğunu unutmayın . Böyle işaretlenmiş bir üyesi olabilir bir değiştirilebilir const
ihlal etmeden yöntemle const
sözleşmesi.
Bir nesnenin belirli bir yöntemin kaç kez çağrıldığını hatırlamasını ve bu yöntemin "mantıksal" sabitliğini etkilememesini istiyorsanız (örneğin) bunu kullanmak isteyebilirsiniz.
Bir const üye Fonksiyon Anlamı de C ++ Ortak Bilgi: Essential Orta Programlama açıklama getiriyordu:
X sınıfının sabit olmayan bir üye işlevindeki bu işaretçinin türü X * sabitidir. Yani, sabit olmayan bir X'in sabit göstergesidir (bkz. Sabit İşaretçiler ve Sabit İşaretçiler [7, 21]). Bunun atıfta bulunduğu nesne sabit olmadığından değiştirilebilir. Bunun bir X sınıfının const üye fonksiyonundaki türü const X * const'tur. Yani, sabit bir X'in sabit göstergesidir. Bunun atıfta bulunduğu nesne sabit olduğundan, değiştirilemez. Sabit ve sabit olmayan üye işlevleri arasındaki fark budur.
Yani kodunuzda:
class foobar
{
public:
operator int () const;
const char* foo() const;
};
Bunu şöyle düşünebilirsiniz:
class foobar
{
public:
operator int (const foobar * const this) const;
const char* foo(const foobar * const this) const;
};
this
değil const
. Değiştirilememesinin nedeni, bir ön değer olmasıdır.
kullandığınızda const
yöntem imzası (sınırlamasına uyan ki: const char* foo() const;
) bellek tarafından işaret olduğu derleyici anlatıyorsun this
(ki bu yöntemle değiştirilemez foo
burada).
Aşağıdaki noktayı eklemek istiyorum.
Ayrıca bir const &
veconst &&
Yani,
struct s{
void val1() const {
// *this is const here. Hence this function cannot modify any member of *this
}
void val2() const & {
// *this is const& here
}
void val3() const && {
// The object calling this function should be const rvalue only.
}
void val4() && {
// The object calling this function should be rvalue reference only.
}
};
int main(){
s a;
a.val1(); //okay
a.val2(); //okay
// a.val3() not okay, a is not rvalue will be okay if called like
std::move(a).val3(); // okay, move makes it a rvalue
}
Cevabı geliştirmekten çekinmeyin. Ben uzman değilim
*this
üye işlevi rvalue-ref-nitelikli olsa ve bir rvalue olarak çağrılsa bile her zaman bir lvalue'dur. Örnek .
Const bir olduğunu fonksiyon beyan belirttiği birlikte kullanılan anahtar kelime const üye işlev ve edecektir değiştirmek mümkün olmayacaktır nesnenin veri üyeleri.
https://isocpp.org/wiki/faq/const-correctness#const-member-fns
"
const
Üye işlevi" nedir?Nesnesini inceleyen (değiştiren) bir üye işlevi.
Bir
const
üye işlevi ile belirtilirconst
sadece üye işlevin parametre listesinden sonra son eki. Bir ile üye fonksiyonlarıconst
soneki “const üye işlevler” veya denir “müfettişler.” Bir olmadan Üyesi fonksiyonlarıconst
soneki “const olmayan üye işlevler” veya denir “mutators.”class Fred { public: void inspect() const; // This member promises NOT to change *this void mutate(); // This member function might change *this }; void userCode(Fred& changeable, const Fred& unchangeable) { changeable.inspect(); // Okay: doesn't change a changeable object changeable.mutate(); // Okay: changes a changeable object unchangeable.inspect(); // Okay: doesn't change an unchangeable object unchangeable.mutate(); // ERROR: attempt to change unchangeable object }
Arama denemesi
unchangeable.mutate()
derleme zamanında yakalanan bir hatadır. Çalışma zamanı alanı veya hız cezası yoktur ve çalışma zamanındaconst
kontrol etmek için test senaryoları yazmanıza gerek yoktur.Üye işlevi
const
üzerindeki izinspect()
, yöntemin nesnenin soyut (istemci tarafından görülebilir) durumunu değiştirmeyeceği anlamına gelmelidir . Bu, yöntemin nesnenin yapısının “ham bitlerini” değiştirmeyeceğini söylemekten biraz farklıdır. C ++ derleyicilerinin, normal olarak çözülemeyen örtüşme sorununu çözemedikleri sürece "bitsel" yorumunu almasına izin verilmez (yani, nesnenin durumunu değiştirebilecek sabit olmayan bir diğer ad bulunabilir). Bu diğer adlandırma sorunundan başka bir (önemli) öngörü: işaretçiden-kanala sahip bir nesneye işaret etmek nesnenin değişmeyeceğini garanti etmez; yalnızca nesnenin bu işaretçi aracılığıyla değişmeyeceğine söz verir .