声明对非const结构的const引用 [英] Declaring a const reference to a non-const structure

查看:89
本文介绍了声明对非const结构的const引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我以为我可以用C ++做到这一点,但似乎无法做到并且它让我烦恼我不能。



我有一堂课像这样的构造函数:

I thought I could do this in C++ but don't seem to be able to and it bugs me I can't.

I have a class with a constructor like such:

TempSensor ( PORT_t& SensorPort ) : Port(SensorPort){};



PORT_t typedef


PORT_t is a typedef

typedef PORT_Struct PORT_t;



PORT_Struct 在头文件中声明,该文件包含在类定义文件中。 />


与此关联的类成员变量声明为


PORT_Struct is declared in a header file which is included in the class definition file.

The class member variable associated with this is declared as

protected:
 PORT_t& Port;



PORT_t 的成员是可读/写的。绝对不是 const



参数 SensorPort in构造函数来自头文件并被声明为一个例子(大约有8个端口,这只是第一个)


The members of PORT_t are read/write. Definitely NOT const.

The argument SensorPort in the constructor comes from a header file and is declared as such as an example (there are about 8 ports, this is just the first)

#define PORTA (*(PORT_t*) 0x620)





所以构造函数在使用将是



So the constructor in use would be

TempSensor T1 ( PORTA );





哪个为 T1 初始化类成员变量,端口,地址0x0620,我想要。



我遇到的问题是,虽然我想要端口被认为是常量所以我以后不能做如下的事情而没有编译时错误



Which does initialize the class member variable for T1, Port, with the address 0x0620 as I want.

The issue I'm having is that, while I want Port to be considered constant so I can't later do something like the following without a compile time error

Port = (*(PORT_t*) 0x123);





我想要 Port 引用的结构保留因为它需要读/写。



只是因为结构的基地址是常量(意味着它存在的位置不能改变)它不遵循然后那个结构的成员也必须是常数(他们不是)。然而编译器似乎这么认为,我无法弄清楚如何声明 Port 来获得我想要的东西。编译器似乎不喜欢任何使用 const 关键字与端口的成员变量声明相关联!它也不像构造函数参数中使用的 const 但也许这是一个不同的问题。



我应该能够声明端口来做我想做的事情,所以对于如何做的任何帮助/建议都非常感激。



也许我只是遗漏了一些东西,但到目前为止,如果是这样,我肯定不会看到它。



哦是的,不,我不能改变声明 PORT_t 的头文件,也不是 PORTA ,......他们就是这样。



这是GCC的最新版本,代码正在编译中,只是Atmel的AVR工作室的一部分,用于为其处理器编译代码。



I DO want the structure that Port references to remain read/write as it needs to be.

Just because the base address of a structure is constant (meaning where in memory it exists which cannot change) it does not follow that then the members of that structure must also be constant (which they're not). Yet the compiler seems to think so and I can't figure out how to declare Port to get what I want. The compiler seems not to like ANY use of the const keyword in association with the member variable declaration of Port! Nor does it like const used in the constructor argument either but maybe this is a different issue.

I should be able to declare Port to do what I want so any help/suggestions as to how to do so are definitely appreciated.

Maybe I'm just missing something but so far, if so, I sure don't see it.

Oh yeah, no I cannot change the header file for the declaration of PORT_t nor for PORTA,... They are what they are.

This is a recent version of GCC the code is being compiled with, simply part of Atmel's AVR studio for compiling code for their processors.

推荐答案

问题似乎和这个问题相同:



http://stackoverflow.com/questions/7181372/w hy-can-i-assign-a-value-to-a-reference-and-can-can-make-a-reference-refe [ ^ ]



The question seems to be the same as this one:

http://stackoverflow.com/questions/7181372/why-can-i-assign-a-new-value-to-a-reference-and-how-can-i-make-a-reference-refe[^]

引用:

我遇到的问题是,虽然我希望Port被认为是常量所以我以后不能做如下的事情而没有编译时错误



Port = (*(PORT_t *)0x123);

The issue I'm having is that, while I want Port to be considered constant so I can't later do something like the following without a compile time error

Port = (*(PORT_t*) 0x123);





以上内容不会更改端口引用的内存地址,但会将0x123下存在的内容复制到端口。字节副本的数量是sizeof(Port_t)。由于您希望Port的成员能够读/写,因此无法解决这个问题。只是理解Port的引用地址是在构造函数中设置的并且不会改变。



The above does not change the address of the memory referenced by Port but copies whatever exists under 0x123 to Port. The number of bytes copies is sizeof (Port_t). Since you want Port's members to be read/write, there's no way around that. Just understand that Port's referential address is set in the constructor and does not change.


Member 8813158写道:
Member 8813158 wrote:



我不想将引用变量声明为const结构实例,而是引用一个const引用变量,该变量引用仍然可更改的结构实例(读/写)。我希望引用变量本身是const,这意味着一旦构造函数通过将结构实例的地址放入其中来初始化它,变量本身就不能分配给它,因为它的const。它所引用的结构实例的成员仍然可以根据需要进行更改。


I do not want to declare a reference variable to a const structure instance and instead a const reference variable that refers to a structure instance that is still changeable (read/write). I want the reference variable itself to be const which means that once the constructor initializes it by putting the address of the structure instance into it, the variable itself cannot be assigned to because its const. The members of structure instance it refers to are still changeable as they need to be.

我看不出这个简单的问题是如何与原始帖子相关的。这就是解决这些问题的方法:



写这样的东西:

I don't see how this simple question is related to the original post. This is how such problems are solved:

Write something like this:

struct Str { int someMember; };

//...

const Str* const someVariable = new Str();
someVariable = new Str(); // won't compile, but why?



最后一行表示您不是要修改 Str 类型的对象,而是尝试修改指针。由于关键字 const ,它将无法编译。哪一个?当然是第二个,在指针符号'*'旁边。 Scratch已经完成,代码将编译。



第一个 const 表示常量对象;它不允许你修改 someVariable->会员



所以,最后的答案是:要通过防止修改指针使对象成为读写,请使用以下声明:


The last line means that you are not trying to modify the object of the type Str but trying to modify the pointer. It won't compile due to the keyword const. Which one? Of course the second one, next to the pointer symbol '*'. Scratch is out and the code will compile.

The first const means the constant object; it won't allow you to modify someVariable->Member.

So, the final answer would be: to make the object read-write by prevent modification of a pointer, use the following declaration:

Str* const someVariable = new Str();



请注意,此表达式不被视为赋值 - 它是初始化;与赋值语句相比,它允许为常量赋值,只允许一次。







感谢您的澄清。忘记上面的内容,让我们来参考一下。你真的很困惑。让我们试着了解它们是什么,但它应该表明你的考虑根本没有意义。考虑一下:


Note that this expression is not considered to be assignment — it is initialization; in contrast to assignment statement it allows to assign some value to a constant, only once.



Thank you for clarifications. Forget the above, lets get to references. You are really confused. Let's try to understand what are they, but it should show your considerations simply make no sense. Consider this:

int a = 1, b = 2;
int& ref = a; // it makes you ref referencing a; let's see:
a = 12; // ref is 12 no
ref = b; // do you think ref started to reference b?
// No, and its easy to check up
// at this point, a became 2. What does it mean?
// it means that previous statement assigned a value 2 to ref
// and, hence to a
// that's it: ref is an alternative name for a
// b is still irrelevant. Do this:
b = 11;
// has ref become 11? No! ref and b are still unrelated



顺便说一句,这就是为什么 ref 应该始终被初始化,因为赋值不能在它和引用的对象之间创建链接。这使得你的实例引用变量在结构中变得不可能:C ++不允许初始化这些成员。



我看不出你的整个想法是否有任何意义。可能,它不能,因为它是基于对C ++引用的本质的误解。你可以阅读它们:

http://www.learncpp.com/cpp-教程/ 611-参考 [ ^ ],

http:// www。 learncpp.com/cpp-tutorial/612-references-vs-pointers-and-member-selection [ ^ ]。



-SA


By the way, that's why ref should always be initialized, as assignment cannot create a link between it and a referenced object. That makes your instance reference variable in structure impossible: C++ does not allow initialization of such members.

I don't see how your whole idea may make any sense. Probably, it cannot, because it was based on the misconception about the nature of C++ references. You can read about them:
http://www.learncpp.com/cpp-tutorial/611-references[^],
http://www.learncpp.com/cpp-tutorial/612-references-vs-pointers-and-member-selection[^].

—SA


如果您希望结构的数据成员是const,请将其声明为const - 您根本不需要引用。如果您不希望结构外部的东西使用它,请将其声明为私有:



If you want a data member of a structure to be const, declare it const - you don't need references at all. If you don't want things outside the struct to use it, declare it private:

struct A
{
    public:
        A( unsigned m ) :m_( m ) {}

        unsigned val() const
        {
            return m_;
        }

        unsigned long square() const
        {
            unsigned long_m_ = m_;
            return long_m_ * long_m_;
        }

        unsigned wont_compile( unsigned new_m )
        {
             m_ = new_m;
        }

    private:
        const unsigned m_;
};

int main()
{
    A a( 37 );
    assert( a.val() == 37 );

    // won't compile - private member
    // remove the private and it still won't compile as m_ is const
    a.m_ = 80;
}





因此,在您的Port类/结构中,您所要做的就是使基地址 const 和/或 private 和snip-snip Bob的yer Aunty。



So in your Port class/structure all you have to do is make the base address const and/or private and snip-snip Bob's yer Aunty.


这篇关于声明对非const结构的const引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆