c++ - 如何利用对私有(结构)成员的公共常量引用进行代码封装
问题描述
在我的错误类中,我只公开了 的常量版本MyStruct
,尝试在初始化列表中初始化对私有成员的常量引用。
我正在调试的程序在功能上等同于以下内容:
#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;
}
对于这个程序,输出如下:
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
但是,在我正在调试的程序中,struct_member_
并且struct_member
正在去同步(常量引用struct_member
被分配到内存中的不同位置——除了它是常量,或者它在更新后失去了轨道struct_member_
——除了它的内存地址不应该改变?)我不确定是哪个或为什么。
关于什么可能导致这种情况发生的任何想法,或者使这种模式适用于非 POD 类型的提示?(无论如何,我计划过渡到基于方法的访问器,因为这个实验似乎失败了。)
解决方案
事实证明,可选项和复制构造函数是所有这些的关键。复制构造函数是默认的,我没有意识到。有趣,因为编译器警告我需要一个非默认值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;
}
};
产生正确的输出:
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
总而言之,仅仅将 getter 公开为方法就不会那么麻烦了。
推荐阅读
- javascript - 康威生命游戏 p5js
- java - @VisibleForTesting() 函数在使用时不会触发生产代码的编译错误
- java - 我可以控制 JVM 选项中的异常吗?
- symfony - symfony 学说 2 OneToMany - 与反边场错误的关联
- gulp - 为什么 Gulp 4 基本选项在我当前的文件夹中生成文件
- javascript - 这个动作创建者在做什么?
- regex - 在一行中的两个单词之间替换正则表达式模式
- android - 如何更改自定义列表适配器中的 ListView 数据?
- html - 使用 COMPASS 进行响应式网站设计
- python - 数据驱动安全 - 第 2 章 - 测试脚本