当前位置: 首页 > 知识库问答 >
问题:

通过临时对象分配给const ref变量的用户定义转换

牧信厚
2023-03-14

下面的代码是我面临的实际问题的简化版本。

假设我没有修改类A(因为它是外部库)的权限,并且它已经在我现有的代码库中广泛使用。

const公司

在这种情况下,如何防止或使其合法化,以便调用者获得正确的A值?

class A 
{
public:
    A() {  }
    A(int _r, int _g, int _b)
        : r(_r), g(_g), b(_b)
    {
    }

    ~A(){ }

    int GetR() const {  return r; }
    int GetG() const { return g; }
    int GetB() const { return b; }

private:
    int r = 0;
    int g = 0;
    int b = 0;
};

class Foo
{
public:
    Foo() : Foo(A()) {}
    Foo(int _r, int _g, int _b) : a(A(_r, _g, _b)) {}
    explicit Foo(const A& _a) : a(_a) {}

    Foo& operator=(const A& a)
    {
        *this = Foo(a);
        return *this;
    }

    operator A() const { return a; }
    operator const A&() const {  return a; }

private:
    A a;
};

int main()
{
    const A& a = Foo(200, 100, 300); 
    std::cout << a.GetR() << a.GetG() << a.GetB() << endl; // I may not get 200 100 300 here as Foo is already out of scope 

    return 0;
}

动机

我为什么要实现上面的类的一些背景。类Foo的实际目的是包含2个不同的对象,它们实际上具有相同的目的,只是内部存储数据的方式不同。例如,让我们说A类和B类,它分别以int和浮动(规范化)存储颜色的RGB值。如上所述,我无权修改类A,它已经在我的代码库中广泛使用。

我的代码库中有很多函数都包含const A


共有1个答案

吕子真
2023-03-14

您可以应用ref限定的成员函数(从C 11开始),即使用左值引用标记转换运算符,以防止在临时对象(rvalues)上调用它。

class Foo
{
public:
    ... ...

    operator A() const { return a; }
    operator const A&() const & {  return a; }
    operator const A&() && = delete;

    ... ...
};

然后呢

const A& a = Foo(200, 100, 300);                 // invalid; invokes deleted operator
const A& a = static_cast<A>(Foo(200, 100, 300)); // fine; invokes operator A()
 类似资料:
  • 问题内容: 就像我们使用__ToString一样,有没有一种方法来定义铸造方法? 问题答案: 无需在php中键入强制类型转换。 编辑: 由于这个话题似乎引起一些混乱,我想我要详细说明一下。 在Java之类的语言中,有两种可能带有类型。编译器有一个关于类型的概念,而运行时还有一个关于类型的想法。编译器的类型与变量相关,而运行时引擎则跟踪值的类型(已将其分配给变量)。变量类型在编译时是已知的,而值类型

  • 用户定义变量 数据库支持用户自定义变量,自定义变量使用@开头,能够被用于任何表达式和参数中。变量是不能持久的,作为范围为 session,这就意味着变量只在定义它的那个 session 里是有效的。一个变量通常使用 SET命 令来声明: SET @USER = 'Joe'; 变量也可以通过使用 SET() 方法来改变值。在查询中可以直接使用: SET @TOTAL = NULL; SELECT

  • 我需要使用一种命名模式创建大量对象,这种命名模式可以通过循环轻松获得。有没有办法像这样从变量中读取对象名? 我不需要为对象分配变量名,只需要在分配时从对象中获取名称即可。

  • 我想把字典的value元素赋给一个字符串变量。 在swiftUI中,字典中的所有值元素都作为字符串返回?类型 什么时候有绳子?类型分配给字符串变量,该字符串变量在swiftUI应用程序中显示为可选(“字符串尝试显示”)。 如何去掉应用程序显示中的“可选”选项?

  • 问题内容: 我正在用JavaScript构建一些对象并将这些对象推入数组,将要使用的键存储在变量中,然后像这样创建对象: 但是,当我尝试检查每个对象的对象数组时,键不是变量键的值。有什么方法可以通过变量设置键的值吗? 问题答案: 您需要先制作对象,然后使用来设置它。 如果您能够使用 ES6 和 Babel ,则可以使用此新功能:

  • 问题内容: 在Python中,对象实例是否可以查看分配给它的变量名?以以下为例: MyObject是否有可能在任何时候看到已将其分配给变量名x?就像它的__init__方法一样? 问题答案: 否。对象和名称位于单独的维度中。一个对象在其生命周期内可以有多个名称,因此无法确定哪个可能是您想要的。即使在这里: 两个名字代表相同的对象(当运行时,在全球范围内)。