Bunun constgibi deklarasyonlarda anlamı nedir ? constBeni karıştırır.
class foobar
{
public:
operator int () const;
const char* foo() const;
};
Bunun constgibi deklarasyonlarda anlamı nedir ? constBeni karıştırır.
class foobar
{
public:
operator int () const;
const char* foo() const;
};
Yanıtlar:
constAnahtar kelimeyi bir yönteme eklediğinizde, thisişaretçi esasen constnesneye bir işaretçi olur ve bu nedenle üye verilerini değiştiremezsiniz. (Kullanmazsanız mutable, daha sonra daha fazla).
constAnahtar kelime, iki benzer yöntemler nesnedir çağrılan birini uygulamak anlamına gelir fonksiyonları imza parçasıdır constve 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, constsü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 mutableve bir constyö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.
constEleme 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 foobaraş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);
constGerç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.
constmı 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, mutablesınıfın veri üyelerine eklenebilecek bir niteleyici olduğunu unutmayın . Böyle işaretlenmiş bir üyesi olabilir bir değiştirilebilir constihlal etmeden yöntemle constsö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;
};
thisdeğil const. Değiştirilememesinin nedeni, bir ön değer olmasıdır.
kullandığınızda constyö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 fooburada).
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 belirtilirconstsadece üye işlevin parametre listesinden sonra son eki. Bir ile üye fonksiyonlarıconstsoneki “const üye işlevler” veya denir “müfettişler.” Bir olmadan Üyesi fonksiyonlarıconstsoneki “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ındaconstkontrol 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 .