繁体   English   中英

C++:为什么我可以将指针值成员变量从 const 成员函数传递给采用非 const 指针参数的外部函数?

[英]C++: Why can I pass a pointer-valued member variable from a const member function to an external function taking a non const pointer parameter?

我正在使用外部库中的函数(这里由printer函数表示)。
偶然地,我注意到,我可以像print()函数那样从const成员函数传递类成员。 即使我编译使用

g++ -Wall -Wextra -Wpedantic -Werror -o test test.cpp

我没有得到错误。

这似乎是非常错误的,因为我实际上是通过调用const成员函数来修改对象。 为什么编译器没有抱怨? 这是代码:

#include <iostream>
using namespace std;

void printer(void* data) {
    static_cast<char*>(data)[0] = '1';
    cout << static_cast<char*>(data) << endl;
}

void setUp(char* data, int length) {
    for(int i=0; i<length; i++)
        data[i] = '0';
    data[length] = '\0';
}

class Test {
    private:
        char* data;

    public:
        Test(int length) {
            data = new char(length+1);
            setUp(this->data, length);
        }

        ~Test() {
            delete data;
        }

        void print() const {
            printer(this->data);
        }
};

int main() {
    Test T(3);
    T.print();
    return 0;
}

我最好的猜测是,编译器只保证指针变量不被修改,即在函数调用后不指向不同的物理地址。 但我也注意到,当我尝试使用std::vector<char>而不是char*和修改后的print函数时,编译器会抛出错误:

void print() const {
    printer(this->myVector.data());
}

所以如果我的猜测是正确的,为什么不能对 STL 向量的data()获得的指针做类似的事情?

  1. 您有一个 char* 数据成员。

  2. 在 const 限定方法的上下文中,这意味着该成员可能不会发生变异。

  3. 该成员是指针。 改变一个指针意味着改变它指向的地方。

  4. 为了清楚起见,方法内的有效限定类型是

     char * const

    不是

     const char *
  5. 这就是为了确认你是绝对正确的

    我最好的猜测是,编译器只保证指针变量不被修改,即在函数调用后不指向不同的...地址。

但是,对于向量,您想要调用数据再次具有有效限定类型std::vector<char> const& ... 所以您需要std::vector::data的 const 限定重载,并且返回const char* 这是您首先期望的,但它与原始指针的行为不同。

不同的原因是向量是为了表达该数据的所有权而编写的,因此常量向量应该具有常量内容。 原始指针可能拥有它们指向的数据,但没有办法表达这一点,也无法为拥有和不拥有原始指针提供不同的 const 行为。 这是尽可能避免使用原始指针的可能原因之一。

这是允许const方法更改数据的常用方法。 Test不变的是指针地址data 这不会被print改变。 尽管如此,您可以自由地改变指针所寻址的内容。

绕过const方法的另一种方法是将成员声明为mutable 可以说,确保内部字符串属性是例如 null 终止用于打印可以被认为是mutable的合法使用。

在 CppCon 2017 上看到 Kate Gregory 的这篇文章,她提供了一个有趣的例子(一个方法被设计为常量,但稍后添加了缓存): https ://youtu.be/XkDEzfpdcSg?t=854

另请参阅此问题以进行有关该主题的热烈讨论: 除了允许通过 const 函数修改变量之外,'mutable' 关键字是否还有其他用途?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM