简体   繁体   English

如何利用对私有(结构)成员的公共常量引用进行代码封装

[英]How to utilize a public constant reference to a private (struct) member for code encapsulation

In my buggy class, I'm only exposing a constant version of MyStruct , experimenting with initializing a constant reference to the private member in an initializer list.在我的越野车 class 中,我只公开了MyStruct的常量版本,尝试在初始化列表中初始化对私有成员的常量引用。

The program I'm debugging is functionally equivalent to the following:我正在调试的程序在功能上等同于以下内容:

#include <iostream>
#include <optional>

struct MyStruct {
  int member = 1;
};

class MyType {
  MyStruct struct_member_;
public:
  MyType() : struct_member(struct_member_) {}
  MyType& operator =(const MyType& other_side) {
    struct_member_ = other_side.struct_member_;
    return *this;
  };
  const MyStruct& struct_member;
  void test() const {
    std::cout << "Why isn't " << &struct_member << " the same as " << &struct_member_ << std::endl;
  }
};

int main()
{
    std::optional<MyType> my = MyType();
    my.value().test();

    std::optional<MyType> yours = MyType();
    yours.value().test();

    my = yours;
    my.value().test();

    my = MyType();
    my.value().test();

    return 0;
}

For this program, here's the output:对于这个程序,这里是 output:

Why isn't 0x7ffeefbff890 the same as 0x7ffeefbff8a0
Why isn't 0x7ffeefbff868 the same as 0x7ffeefbff878
Why isn't 0x7ffeefbff890 the same as 0x7ffeefbff8a0
Why isn't 0x7ffeefbff890 the same as 0x7ffeefbff8a0

However, in the program I'm debugging, struct_member_ and struct_member are getting desynchronized (either the const reference struct_member is getting assigned to a different place in memory-- except it's const, or it's loosing track with an updated struct_member_ -- except its memory address shouldn't change?) and I'm not sure which or why.但是,在我正在调试的程序中, struct_member_struct_member正在变得不同步(const 引用struct_member被分配到内存中的不同位置——除了它是 const,或者它正在丢失带有更新的struct_member_的轨道——除了它的 memory地址不应该改变?)我不确定是哪个或为什么。

Any ideas on what could lead to this happening, or tips to make this pattern work with non-POD types?关于什么可能导致这种情况发生的任何想法,或者使这种模式适用于非 POD 类型的技巧? (I plan to be transitioning to method-based accessors anyway, since this experiment seems to be failing.) (无论如何,我计划过渡到基于方法的访问器,因为这个实验似乎失败了。)

Turns out optionals and copy constructors were key to all of this.事实证明,可选项和复制构造函数是所有这一切的关键。 The copy constructor was defaulting and I didn't realize it.复制构造函数是默认的,我没有意识到。 Funny, because the compiler warned that I needed a non-default operator= , but didn't afford me the same warning for the copy constructor.有趣的是,因为编译器警告我需要一个非默认的operator= ,但没有为复制构造函数提供相同的警告。

class MyType {
  MyStruct struct_member_;
public:
  MyType() : struct_member(struct_member_) {
    std::cout << "constructor" << std::endl;
  }
  MyType(const MyType& other) : struct_member(struct_member_) {
    std::cout << "copy constructor " << std::endl;
    struct_member_ = other.struct_member_;
  };
  MyType& operator =(const MyType& other_side) {
    std::cout << "assignment operator called" << std::endl;
    struct_member_ = other_side.struct_member_;
    return *this;
  };
  const MyStruct& struct_member;
  void test() const {
    std::cout << "Why isn't " << struct_member.member << ": " << &struct_member << " the same as " << &struct_member_ << std::endl;
  }
};

Yields the correct output:产生正确的 output:

constructor
copy constructor 
Why isn't 0x7ffeefbff8a0 the same as 0x7ffeefbff8a0
constructor
copy constructor 
Why isn't 0x7ffeefbff878 the same as 0x7ffeefbff878
assignment operator called
Why isn't 0x7ffeefbff8a0 the same as 0x7ffeefbff8a0
constructor
assignment operator called
Why isn't 0x7ffeefbff8a0 the same as 0x7ffeefbff8a0

Altogether, it'd be less hassle just to expose getters as methods.总而言之,将 getter 公开为方法会更简单。

Either delete the copy constructor (because the default behavior binds the reference to the "wrong" thing in this case):要么删除复制构造函数(因为默认行为在这种情况下将引用绑定到“错误”的东西):

MyType(MyType const&) = delete;

Or provide a copy constructor that does the right thing, by binding the public const accessor to the self-same object:或者通过将公共 const 访问器绑定到相同的 object 来提供一个做正确事情的复制构造函数:

MyType(MyType const& other)
  : struct_member_{other.struct_member_}
  , struct_member(struct_member_) {}

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

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