当我对该类的对象有 const 引用时,该类的非 const 内部成员是否会变为 const?

发布于 2024-08-13 23:07:39 字数 1887 浏览 4 评论 0原文

嗯,我认为我的问题源于基本 C++ 概念的知识湖。问题是,在我的代码(如下)中,我有 Header 和 Register 类。对于这两者,我传递了对已打开的 ifstrem 文件的引用。标头从中读取一些字节。 Register 有一个方法返回 Header 的引用(在 Register 构造函数中传递)。

问题是,当我将对 Header 的引用声明为 const(在我的 Register 类中)时,我收到一条错误消息:

error C2662: 'Header::Field_1' : cannot convert 'this' pointer from 'const Header' to 'Header &'

我猜问题是:

Field_1 方法通过eekg 更改文件光标。因此这个成员对象不能是const(它的内部结构正在改变)。在 Header 类中声明 fstream _stream,并且拥有该类的 const 引用,是否也会使其所有内部成员成为 const?

PS:我使用的是 VS C++ Express。下面的代码没有做任何有用的事情,只是一个例子。

// ********** HEADER.H ***********
#ifndef __HEADER_H__
#define __HEADER_H__

#include <fstream>

class Header
{
    private:

        std::ifstream* _stream;
        unsigned long field1;

    public:

        Header(std::ifstream* stream);
        ~Header() { }

        unsigned long Field_1(void);
};

class Register
{
    private:
        const Header& _header;
        std::ifstream* _stream;

    public:

        Register(const Header& header, std::ifstream* stream);
        ~Register(){ }

        const Header& GetHeader(void) { return _header; }
};

#endif /*__HEADER_H__*/

//********* PROGRAM.CPP *************

#include <iostream>
#include "header.h"

using namespace std;

Header::Header(ifstream* stream) : _stream(stream)
{
}

unsigned long Header::Field_1(void)
{
    _stream->seekg(0x00, fstream::beg);
    _stream->read(reinterpret_cast<char*>(&field1), sizeof(field1));
    return field1;
}


Register::Register(const Header& header, std::ifstream* stream): _header(header), _stream(stream)
{
}

int main(void)
{
    ifstream file("test.dat", ios::binary | ios::in);
    Header h(&file);
    Register reg(h, &file);

    cout << "Field 1 " << reg.GetHeader().Field_1() << endl;

    file.close();
    return 0;
}

Well, I think my problem originates in a lake of knowledge of basic C++ concepts. The problem is, in my code (below) I have the classes Header and Register. For both, I pass a reference to a ifstrem file already opened. The Header reads some bytes from it. Register has a method to return a reference of Header (which is passed in Register constructor).

The problem is, when I declare the reference to Header as const (in my Register class), I've got an error message saying:

error C2662: 'Header::Field_1' : cannot convert 'this' pointer from 'const Header' to 'Header &'

The problem, I guess, is:

Field_1 method changes the file cursor through seekg. therefore this member object cannot be const (its internal structure is being changed). Being fstream _stream declared inside Header class, and having a const reference for this class does it make all its internal members const as well?

PS: I'm using VS C++ express. The code below doesn't do anything useful, is just an example.

// ********** HEADER.H ***********
#ifndef __HEADER_H__
#define __HEADER_H__

#include <fstream>

class Header
{
    private:

        std::ifstream* _stream;
        unsigned long field1;

    public:

        Header(std::ifstream* stream);
        ~Header() { }

        unsigned long Field_1(void);
};

class Register
{
    private:
        const Header& _header;
        std::ifstream* _stream;

    public:

        Register(const Header& header, std::ifstream* stream);
        ~Register(){ }

        const Header& GetHeader(void) { return _header; }
};

#endif /*__HEADER_H__*/

//********* PROGRAM.CPP *************

#include <iostream>
#include "header.h"

using namespace std;

Header::Header(ifstream* stream) : _stream(stream)
{
}

unsigned long Header::Field_1(void)
{
    _stream->seekg(0x00, fstream::beg);
    _stream->read(reinterpret_cast<char*>(&field1), sizeof(field1));
    return field1;
}


Register::Register(const Header& header, std::ifstream* stream): _header(header), _stream(stream)
{
}

int main(void)
{
    ifstream file("test.dat", ios::binary | ios::in);
    Header h(&file);
    Register reg(h, &file);

    cout << "Field 1 " << reg.GetHeader().Field_1() << endl;

    file.close();
    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

嘦怹 2024-08-20 23:07:39

是的,当 GetHeader() 返回 Header 对象的 const 引用时,您只能对其调用 const 方法。
在这种情况下,如果您通过以下方式将 Field_1 声明为 const 方法:(

unsigned long Header::Field_1(void) const

注意末尾的 const),

问题是如果您这样做,则在 const 方法内的所有其他内容成员看起来也好像是 const (除非您将它们标记为可变)。

因此,您可能会遇到 reinterpret_cast(&field1) 问题。

在这种情况下,最简单的解决方案可能是让 GetHeader() 返回一个非常量引用。或者,您可以将 field1 标记为 mutable (但如果您沿着这条路走下去,请确保您首先了解 mutable 的语义和危险。我的感觉是,让 GetHeader() 返回一个非常量引用才是您真正要做的。想要这里)

Yes, when GetHeader() returns a const reference to the Header object, you can only call const methods on it.
In this case if you declare Field_1as a const method by writing:

unsigned long Header::Field_1(void) const

(note the const on the end)

The trouble is if you do this then within the const method all other members appear as if they are const too (unless you mark them as mutable).

As a result you will probably have trouble with the reinterpret_cast<char*>(&field1).

In which case the simplest solution is probably to have GetHeader() return a non-const reference. Alternatively you could mark field1 as mutable (but make sure you understand the semantics and dangers of mutable first if you go down that route. My feeling is that making GetHeader() return a non const reference is what you really want here)

秉烛思 2024-08-20 23:07:39

Register::GetHeader() 函数返回一个 const Header &。因此,您不能通过此引用调用任何非常量成员函数。

为了解决您的问题,我希望您希望将 Header::Field_1() 函数设置为常量。

IE。声明为 unsigned long Field_1(void) const;

The Register::GetHeader() function returns a const Header &. Therefore you cannot call any non-const member functions through this reference.

To fix your problem, i expect you want to make the Header::Field_1() function const.

ie. declared as unsigned long Field_1(void) const;

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文