提问人:user137263 提问时间:4/22/2013 最后编辑:Alex Chamberlainuser137263 更新时间:4/22/2013 访问量:338
C++:类变量如何修改?
C++ : how does class variable get modified?
问:
从有关 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
答:
setMonth 是 Date 类的成员方法,因此可以查看 Date 类的所有成员变量
void Date::setMonth( int mn )
{
month = mn; // Modifies data member
}
mn 作为参数传入。这样,无论您作为参数放置的任何内容,都将分配给类的 month 成员变量。
setMonth
是一个成员函数。因此,它有一个隐式指针指向它正在操作的对象。也就是说,特定对象的每个成员变量都在作用域内,(非常量)成员函数可以修改它们。this
重写可能更清楚,setMonth
void Date::setMonth( int mn )
{
this->month = mn; // Modifies data member
}
此外,函数如何知道月份变量以在不传入的情况下对其进行修改?
成员函数(如 )隐式接收指向调用它们的类型(在本例中)的对象的指针。对于限定为 的成员函数,指针是指向 的指针,它不允许修改所指向对象的状态。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
const
const
这就是为什么你不能在类型为 -qualified 的对象上调用本身不限定的成员函数:对象的状态永远不应该被改变,非函数也不承诺永远不会改变它。const
const
const
const
因此,编译器将通过引发错误来阻止您对限定类型(例如)的对象调用非函数(例如)。const
Date::setMonth()
const
const Date
评论
通过定义对象,可以向编译器保证对象的状态不会改变。它保持状态,就像它被创建一样。
调用方法时,无论是按引用还是按值传递,您都在更改对象的状态。const
setMonth()
void Date::setMonth( int mn )
{
month = mn; // Modifies data member <--- Trying to modify the whole object by changing a part of it
}
答案是,声明的函数表示该函数不会修改调用该函数的对象。也就是说,如果您这样做:const
BirthDate.getMonth();
这是可以的,因为 while 是 ,被声明,因此保证它不会改变它。BirthDate
const Date
getMonth
const
这不起作用的原因:
BirthDate.setMonth( 4 );
是 没有 声明 的 ,这意味着它不 保证 它 不会 改变 , 即 它 被 调用 的 对象 。setMonth
const
BirthDate
更改的不是输入参数,而是调用函数的对象。在 的情况下,修改的是实例中的变量。setMonth
month
Date
至于程序如何知道函数会修改对象:它没有。但是你不能调用一个未在对象上声明的函数,该函数是 .此外,尝试修改声明的函数中的(非)成员变量将产生编译器错误。因此,编译器确保您不会违背承诺。(虽然自然而然地,有一些邪恶的符合标准的方式偷偷地违背了这个承诺。但这是不道德和危险的。const
const
mutable
const
MyDate
是类的对象。
每个对象都有自己的对象,自从它被声明以来,它是已知的。(即使从类之外,您也知道它包含一个,但您无法访问它,因为它是私有的。
您还可以使用指针(它是每个类中指向自己的内存位置的指针)。Date
Date
int month
Date
int month
this
setMonth 的代码隐式执行以下操作:
void Date::setMonth( int mn )
{
(*this).month = mn; // Modifies data member
}
评论
month
因为分配而被“修改”了?它甚至在评论中这样说:“修改数据成员”setMonth