-1

来自有关const 函数的 MSDN 页面

编码:

    // constant_member_function.cpp
class Date
{
public:
   Date( int mn, int dy, int yr );
   int getMonth() const;     // A read-only function
   void setMonth( int mn );   // A write function; can't be const
private:
   int month;
};

int Date::getMonth() const
{
   return month;        // Doesn't modify anything
}
void Date::setMonth( int mn )
{
   month = mn;          // Modifies data member
}
int main()
{
   Date MyDate( 7, 4, 1998 );
   const Date BirthDate( 1, 18, 1953 );
   MyDate.setMonth( 4 );    // Okay
   BirthDate.getMonth();    // Okay
   BirthDate.setMonth( 4 ); // C2662 Error
}

但是如何month在函数中进行修改setMonth?该函数按值传递并且不返回任何内容。此外,函数如何知道月份变量以在不传入的情况下对其进行修改?

4

6 回答 6

5

此外,函数如何知道月份变量以在不传入的情况下对其进行修改?

成员函数(如setMonth())隐式接收this指向Date它们被调用的类型(在这种情况下)对象的指针。对于限定为const的成员函数,this指针是指向 的指针const,它不允许您修改指向对象的状态。

事实上,如下:

void Date::setMonth( int mn )
{
    month = mn;          // Modifies data member
}

等价于以下内容:

void Date::setMonth( int mn )
{
    this->month = mn;          // Modifies data member
//  ^^^^^^
//  "this" is a pointer to an object of type Date (i.e. Date*),
//  and that is the object on which setMonth() is invoked
}

所有其他成员函数的情况相同,因此:

int Date::getMonth() const
{
    return month;        // Doesn't modify anything
}

相当于:

int Date::getMonth() const
//                   ^^^^^ Means the implicit "this" pointer is const
{
    return this->month;        // Doesn't modify anything
//         ^^^^^^
//         Here, "this" is a pointer to a CONST Date object (i.e. Date const*),
//         and that is the object on which getMonth() is invoked
}

重要提示:如果调用成员函数的对象具有-qualified 类型,则隐式this指针实际上是一个指针。constconst

const这就是为什么您不能在类型 const-qualified的对象上调用本身不是 -qualified 的成员函数:对象的状态 const 永远不应该被改变,并且非const函数不承诺永远不会改变它。

因此,编译器将通过引发错误来阻止您在- 限定类型(例如)的对象上调用非const函数(例如)。Date::setMonth()constconst Date

于 2013-04-22T10:15:02.453 回答
1

答案是const声明的函数表示该函数不会修改调用该函数的对象。也就是说,如果你这样做:

BirthDate.getMonth();

这没关系,因为 whileBirthDate是一个const Date,getMonth被声明const,因此保证它不会改变它。

这不起作用的原因:

BirthDate.setMonth( 4 );

setMonth没有声明const的,这意味着它不保证它不会改变BirthDate,即调用它的对象。

改变的不是输入参数,而是调用函数的对象。在 的情况下setMonth,它是month您的实例中的变量Date被修改。

至于程序如何知道该函数将修改一个对象:它不知道。但是你不能调用一个没有const在一个对象上声明的函数const。此外,尝试mutable在声明的函数中修改(非)成员变量const会给您带来编译器错误。因此,编译器确保您不会违背承诺。(当然,有一些邪恶的符合标准的方式偷偷违背这个承诺。但这只是不道德和危险的。)

于 2013-04-22T10:16:57.870 回答
1

setMonth是成员函数。this因此,它有一个指向它正在操作的对象的隐式指针。也就是说,特定对象的每个成员变量都在范围内,并且(非常量)成员函数可以修改它们。

重写可能会更清楚setMonth

void Date::setMonth( int mn )
{
   this->month = mn;          // Modifies data member
}
于 2013-04-22T10:14:22.640 回答
1

setMonth 是 Date 类的成员方法,因此可以看到 Date 类的所有成员变量

void Date::setMonth( int mn )
{
   month = mn;          // Modifies data member
}

mn作为参数传入。这样,无论您作为参数输入什么,都将分配给该类的月份成员变量。

于 2013-04-22T10:13:24.497 回答
0

MyDateDate类的对象。每个Date对象都有自己的int month,因为它被声明了。(即使从您知道Date包含 anint month但您无法访问它的类外部,因为它是私有的。您也可以使用this指针(这是每个类中可用的指针,指向 ist 自己的内存位置)。

setMonth 的代码隐含地执行以下操作:

void Date::setMonth( int mn )
{
   (*this).month = mn;          // Modifies data member
}
于 2013-04-22T10:17:18.310 回答
0

通过定义您的对象,const您可以向编译器保证对象的状态不会改变。它保持在创建时的状态。
当调用你的方法setMonth()时,你正在改变对象的状态,不管你是通过引用还是通过值。

void Date::setMonth( int mn )
{
   month = mn;          // Modifies data member <--- Trying to modify the whole object by changing a part of it
}
于 2013-04-22T10:15:17.720 回答