const和c ++中没有const方法?

时间:2010-10-15 15:21:06

标签: c++ const-correctness

我有一个程序,它的许多类都有一些带有关键字const的运算符和方法,如下所示:

operator const char* () const;
operator char* ();
void Save(const char *name) const;
void Load(const char *name);

首先:在方法声明结束时它是什么意思?是什么意思就像把它放在开头一样?

第二:为什么需要const版本而不需要const版本的operator()?

提前致谢。

8 个答案:

答案 0 :(得分:8)

  

首先:在方法声明结束时它是什么意思?是什么意思就像把它放在开头一样?

没有。最后的const表示可以在声明为const的对象上调用该方法。开头的const表示返回的值为const

  

第二:为什么需要const版本而不需要const版本的operator()?

非const版本返回char*,它不是const。通过修改此char*,您实际上可以修改对象(假设char*是对象的成员)。

由于const个对象不允许这样做,因此const对象的重载为operator(),因此返回const char*,因此无法通过它修改对象

答案 1 :(得分:2)

成员函数constness。这意味着该函数不能(*)修改任何成员变量。这就像在一个函数调用中将const放在所有成员变量的前面。它是您班级客户的良好保证,也可能有助于编译器优化。

(*) - 另见关键字mutable。

答案 2 :(得分:2)

最后的

'const'告诉编译器此方法不会更改任何成员变量 - 在const实例上调用此方法是安全的。因此,可以在const实例上调用Save,因为它不会更改该实例。另一方面,加载将更改实例,因此不能在const实例上使用。

operator()的const版本传回一个const指针,保证传回的缓冲区不会改变。据推测,这是指向类的实例变量的指针。对于非const实例,另一个operator()传回一个非const指针。它必须是一个指向某些内存的指针,即使写入,也不会改变实例的内容。

此外,有时查找'mutable'关键字。理解这将有助于您理解这种const正确性的想法。

答案 3 :(得分:1)

const放在方法声明的末尾,表明对象本身或thisconst而不是返回类型。

由于复杂的原因,C ++允许在const上重载方法。这里没有足够的空间来详细介绍。但这里有几个简短的。

  • 偶然地,当从const类型调用方法时,方法的行为会有所不同,或者有必要。最直接的示例是当您想要从const方法返回const值和从常规方法返回非常量值时。
  • thisconst是否会显着改变内部方法的绑定。到了它本质上将成为两个不同的方法体。因此将它分解为两种不同的方法是有意义的。

答案 4 :(得分:1)

除了其他答案之外还有一个注释:示例中没有operator()

operator const char* () const;
operator char* ();

是转换运算符,这意味着类的对象可以隐式转换为C风格的字符串,例如

void f(const MyClass& x, MyClass& y) {
  const char* x_str = x;
  char* y_str = y;
}

operator()的声明和用法,这意味着您可以使用类似于函数的类类型的对象,如下所示:

class MyClass {
public:
  const char* operator() (int x, int y) const;
  // ...
};

void g(const MyClass& obj) {
  const char* result = obj(3, 4);
}

答案 5 :(得分:1)

如果您正在寻找有关C ++的优秀资源(包括正确使用const的提示),请尝试“Effective C ++”。

有关此内容的有用网站:JRiddel.org

在C ++中,当您通过将方法签名放在方法签名之后声明方法const时,您声明“此方法不会更改正在调用的对象中的任何非mutable实例变量” 。“

返回值之前的const(例如:operator const char*..."中的const)声明它只返回指向const char*的变量指针。 (您可能不会更改char*的内容,但可以重新指定指针。)如果您编写了“const char* const ...”,它将是指向常量字符的常量指针。 (const来自明星之后)。

多个版本很有用,因此编译器可以理解这一点:

const char* my_const_var = <object_name>();
char* my_var = <object_name>();

克里斯

答案 6 :(得分:1)

您应该参考“ HIGH·INTEGRITY C ++ CODING STANDARD STUAL MANUAL ”,了解何时建议对班级成员使用 const 修饰符:

高完整性CPP规则3.1.8 :声明'const'任何不修改对象外部可见状态的类成员函数。 (QACPP 4211,4214)

对齐:虽然语言强制执行按位const正确性,但const正确性应该被认为是逻辑的,而不是按位的。如果客户端无法确定对象是否因调用该函数而发生更改,则应将成员函数声明为const。 'mutable'关键字可用于声明可在const函数中修改的成员数据,这只应在成员数据不影响对象外部可见状态的情况下使用。

class C 
{ 
public: 
     const C& foo() { return * this; }    // should be declared const 
     const int& getData() { return m_i; } // should be declared const 
     int bar() const { return m_mi; }     // ok to declare const 
private: 
int m_i; 
mutable int m_mi; 
};

参考有效C ++第21项;工业实力C ++ 7.13;

答案 7 :(得分:0)

  1. 开头的Const适用于返回值。最后的Const适用于方法本身。当您将方法声明为“const”时,您说您无意修改方法中类的任何成员变量。编译器甚至会进行一些基本检查,以确保该方法不会修改成员变量。返回值中的const可防止调用者修改返回的值。当您返回指针或对类管理的数据的引用时,这可能很有用。这通常是为了避免返回复杂数据的副本,这些副本在运行时可能很昂贵。

  2. 你有两个不同运算符的原因是“const”版本返回一个const指针,该指针可能是类内部的数据。如果类的实例是const,那么您希望返回的数据也应该是const。 “非const”版本只提供了一种方法,当调用者具有类的非const实例时,该方法返回可修改的返回值。

相关问题