为什么 const 正确性规则不适用于内置库?
Why const correctness rule doesn't work for built in libraries?
const 方法有一条规则。如果方法是 const,而我们试图在同一个方法中使用另一个函数,那么它也应该是 const。否则,我们将出现编译错误。我试图在 math.h 库中找到 abs() 函数的声明,这是我找到的:Declarations of abs()
这意味着 abs() 函数不是 const,但是当我在 const 方法中使用它时,我没有出现编译错误。有人可以解释这是为什么吗?
class D:public B,C
{
public:
D()
{
cout<<"This is constuctor D"<<endl;
}
int fun3() const;
~D()
{
cout<< "Destructor D"<<endl;
}
};
int D::fun3() const
{
int x=-3;
return abs(x);
}
这里对const
成员函数的约束有误解
一个const
成员函数可以调用它想要的任何函数,只要它不改变对象的状态。所以 fun3()
编译得非常好,因为它不会更改任何成员变量,也不会为同一对象调用任何非常量成员函数。
重要说明: public B,C
可能不是你想的那样:这意味着D公开继承自B,私有来自 C。如果您希望它从 C 公开继承,则必须声明 public B, public C
。
const
应用于方法仅意味着 this
指针,即指向该方法正在运行的实例的指针,是 const
。这意味着它不能修改字段,只能调用 const
方法 在它上面 ,一般情况下不会。
调用自由函数是完全可以接受的,甚至可以在同一 class 的 不同对象 上调用非 const
方法,只要因为这样的对象不是 const
。
首先,忘记你认为你知道的东西。让我们看看成为 const
会员意味着什么。
class D {
public:
int fun2();
int fun3() const;
};
这说明了什么?有个叫D
的class。有两个成员函数 fun2
和 fun3
,每个函数都有一个隐藏的 this
参数,没有其他参数。
坚持住!隐藏参数?嗯,是。您可以在函数内使用 this
;它的价值必须来自某个地方。所有非静态成员函数都有这个隐藏参数。但是,并非所有非静态成员函数都具有相同类型的隐藏参数。如果我要显示隐藏参数,声明将如下所示:
int D::fun2(D * this);
int D::fun3(const D * this);
请注意 const
是如何存在于这个伪声明中的?这就是声明一个 const
成员函数的效果:this
指向一个 const
对象而不是一个非 const
对象。
现在回到问题。 fun3
可以调用 fun2
吗?那么,fun3
会将它的 this
指针(一个指向常量对象的指针)传递给 fun2
,它需要一个指向对象的指针。那将意味着失去常量,所以这是不允许的。
可以fun3
调用abs
吗?那么,fun3
会将一个整数传递给 abs
。这里没问题。问题是失去了 this
的常量性。只要避免这种情况,就可以了。
考虑一下
#include <iostream>
int f(int num) { return num+1; }
int fr(int& num) { return num+1; }
int fcr(const int& num) { return num+1; }
class D
{
public:
int value= 0;
public:
void f1() { value++; }
int f2() const { return value; }
int f3() { return value; }
static void f4() { std::cout << "Hello" << std::endl; }
void f5() const;
};
void D::f5() const
{
// Prohibited:
// f1(); // modifies this
// f3(); // might modify this
// value++; // modifies this->value, thus modifies this
// value= 2; // modifies this->value, thus modifies this
// value= abs(value); // modifies this->value, thus modifies this
// fr(value); // takes value by reference and might modify it
//
// Permitted:
f2(); // const function, does not modify this
std::cout << value << std::endl; // independent function, does not modify this; read access to this->value is const
std::cout << abs(value) << std::endl; // independent function, does not modify this; read access to this->value is const
f4(); // static function, does not modify this
f(value); // function, does not modify this; takes value as read only (makes copy)
fcr(value); // function, does not modify this; takes value as read only by reference
D otherObject;
otherObject.f1(); // modifies otherObject (non const), does not modify this
}
int main()
{
const D d;
d.f5();
}
每当你在 f5()
中调用像 f4()
这样的成员函数时,你传递的是一个隐式的 this
指针,相当于 this->f4()
。在 f5()
中,因为它是 const
,所以它不是 D*
类型,而是 const D*
类型。所以你不能做 value++
(相当于 this->value++
对于 const D*
。但是你可以调用 abs
、printf
或任何不需要 this
并尝试修改它)。
当你取this->value
时,如果this
类型是D*
,它的类型是int
,你可以自由修改它。如果你对 const D*
做同样的事情,它的类型变成 const int
,你不能修改它,但可以复制它并作为常量引用访问它以供读取。
const 方法有一条规则。如果方法是 const,而我们试图在同一个方法中使用另一个函数,那么它也应该是 const。否则,我们将出现编译错误。我试图在 math.h 库中找到 abs() 函数的声明,这是我找到的:Declarations of abs() 这意味着 abs() 函数不是 const,但是当我在 const 方法中使用它时,我没有出现编译错误。有人可以解释这是为什么吗?
class D:public B,C
{
public:
D()
{
cout<<"This is constuctor D"<<endl;
}
int fun3() const;
~D()
{
cout<< "Destructor D"<<endl;
}
};
int D::fun3() const
{
int x=-3;
return abs(x);
}
这里对const
成员函数的约束有误解
一个const
成员函数可以调用它想要的任何函数,只要它不改变对象的状态。所以 fun3()
编译得非常好,因为它不会更改任何成员变量,也不会为同一对象调用任何非常量成员函数。
重要说明: public B,C
可能不是你想的那样:这意味着D公开继承自B,私有来自 C。如果您希望它从 C 公开继承,则必须声明 public B, public C
。
const
应用于方法仅意味着 this
指针,即指向该方法正在运行的实例的指针,是 const
。这意味着它不能修改字段,只能调用 const
方法 在它上面 ,一般情况下不会。
调用自由函数是完全可以接受的,甚至可以在同一 class 的 不同对象 上调用非 const
方法,只要因为这样的对象不是 const
。
首先,忘记你认为你知道的东西。让我们看看成为 const
会员意味着什么。
class D {
public:
int fun2();
int fun3() const;
};
这说明了什么?有个叫D
的class。有两个成员函数 fun2
和 fun3
,每个函数都有一个隐藏的 this
参数,没有其他参数。
坚持住!隐藏参数?嗯,是。您可以在函数内使用 this
;它的价值必须来自某个地方。所有非静态成员函数都有这个隐藏参数。但是,并非所有非静态成员函数都具有相同类型的隐藏参数。如果我要显示隐藏参数,声明将如下所示:
int D::fun2(D * this);
int D::fun3(const D * this);
请注意 const
是如何存在于这个伪声明中的?这就是声明一个 const
成员函数的效果:this
指向一个 const
对象而不是一个非 const
对象。
现在回到问题。 fun3
可以调用 fun2
吗?那么,fun3
会将它的 this
指针(一个指向常量对象的指针)传递给 fun2
,它需要一个指向对象的指针。那将意味着失去常量,所以这是不允许的。
可以fun3
调用abs
吗?那么,fun3
会将一个整数传递给 abs
。这里没问题。问题是失去了 this
的常量性。只要避免这种情况,就可以了。
考虑一下
#include <iostream>
int f(int num) { return num+1; }
int fr(int& num) { return num+1; }
int fcr(const int& num) { return num+1; }
class D
{
public:
int value= 0;
public:
void f1() { value++; }
int f2() const { return value; }
int f3() { return value; }
static void f4() { std::cout << "Hello" << std::endl; }
void f5() const;
};
void D::f5() const
{
// Prohibited:
// f1(); // modifies this
// f3(); // might modify this
// value++; // modifies this->value, thus modifies this
// value= 2; // modifies this->value, thus modifies this
// value= abs(value); // modifies this->value, thus modifies this
// fr(value); // takes value by reference and might modify it
//
// Permitted:
f2(); // const function, does not modify this
std::cout << value << std::endl; // independent function, does not modify this; read access to this->value is const
std::cout << abs(value) << std::endl; // independent function, does not modify this; read access to this->value is const
f4(); // static function, does not modify this
f(value); // function, does not modify this; takes value as read only (makes copy)
fcr(value); // function, does not modify this; takes value as read only by reference
D otherObject;
otherObject.f1(); // modifies otherObject (non const), does not modify this
}
int main()
{
const D d;
d.f5();
}
每当你在 f5()
中调用像 f4()
这样的成员函数时,你传递的是一个隐式的 this
指针,相当于 this->f4()
。在 f5()
中,因为它是 const
,所以它不是 D*
类型,而是 const D*
类型。所以你不能做 value++
(相当于 this->value++
对于 const D*
。但是你可以调用 abs
、printf
或任何不需要 this
并尝试修改它)。
当你取this->value
时,如果this
类型是D*
,它的类型是int
,你可以自由修改它。如果你对 const D*
做同样的事情,它的类型变成 const int
,你不能修改它,但可以复制它并作为常量引用访问它以供读取。