【问题标题】:Do non const internal members of class become const when I have const ref to an object of that class?当我对该类的对象有 const ref 时,类的非 const 内部成员是否会变为 const?
【发布时间】:2009-12-03 13:58:24
【问题描述】:

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

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

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

我想问题是:

Field_1 方法通过 seekg 改变文件光标。因此这个成员对象不能是 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;
}

【问题讨论】:

  • 你为什么声明Register::GetHeader(void)首先返回一个const Header&amp;

标签: c++ reference constants


【解决方案1】:

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

unsigned long Header::Field_1(void) const

(注意最后的 const)

问题是如果你这样做,那么 const 方法中所有其他成员看起来也好像是 const(除非你将它们标记为可变)。

因此,您可能会遇到reinterpret_cast&lt;char*&gt;(&amp;field1) 的问题。

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2013-01-07
      • 1970-01-01
      • 1970-01-01
      • 2021-07-25
      • 2021-02-05
      • 2019-04-01
      相关资源
      最近更新 更多