【问题标题】:In C++ is it possible to return an element of the class from a class member function?在 C++ 中,是否可以从类成员函数返回类的元素?
【发布时间】:2020-05-31 05:55:54
【问题描述】:

在 C++ 中,是否可以从类成员函数返回类的元素?

namespace translation2d
{
    class translation2d
    {
        public:
           double x;
          double y;

        public:
            translation2d()
            {
                x=0;
                y=0;
            }

        public:
            translation2d translateBy(translation2d other); 
            //being interpreted as a constructor?
    }

    translation2d translation2d::translateBy(translation2d other)
    {//I need this member function to return an object of type translation2d
        x+=other.x;
        y+=other.y;
    }
};

【问题讨论】:

  • 你试过了吗:return translation2d(); ?
  • 通过调用translateBy(...) 修改您的translation2d 对象。您需要返回当前translation2d 对象的副本还是新的translation2d 对象?
  • “是”,类成员可以创建与定义它的类具有相同类型的对象。(不确定问题中还有什么问题..因此投票焦点- 必需。)

标签: c++ function class member


【解决方案1】:

当然,有类似的东西

struct Translation2d {
    double x, y;
    Translation2d(double x, double y) : x(x), y(y) {}
    Translation2d translate_by(const Translation2d& other) {
        return Translation2d(x + other.x, y + other.y);
    }
};

【讨论】:

    【解决方案2】:

    6502的回答正确,代码整洁。

    为了清楚起见,我只是想提供一个最小化对原始代码更改的修复:

    translation2d translation2d::translateBy(translation2d other)
    {
        translation2d copy = *this;
    
        copy.x += other.x;
        copy.y += other.y;
    
        return copy;
    }
    

    这个想法是:

    1. 创建“当前”对象的副本,这样您就不会影响原始对象(您不希望这样)
    2. 使用来自other 的数据调整后返回该副本

    换一种写法,我们可以避免复制参数再次,因为您已经按值传递了它:

    translation2d translation2d::translateBy(translation2d copy)
    {
        copy.x += this->x;
        copy.y += this->y;
    
        return copy;
    }
    

    ...虽然我希望编译器在现实中为您执行此操作,但我发现此版本的代码更难阅读。有关避免额外副本的其他方法,请参阅此答案的最后一部分(假设您倾向于担心它)。


    这个函数的另一个版本实际上会转换 当前 对象而不是返回一个新对象:

    translation2d& translation2d::translateBy(translation2d other)
    {
        this->x += other.x;
        this->y += other.y;
    
        return *this;
    }
    

    请注意,我仍然返回一些东西,而不是 void;在这种情况下,我遵循了返回对当前对象的引用的约定,这有助于将多个修改链接到同一个对象。您会在运算符重载中发现很多这种模式。

    从技术上讲,this-> 是不必要的,但它使函数更容易理解。


    请注意,6502 将函数更改为通过 const-reference 获取 other,这通常是一个好主意,您也应该考虑这样做(尽管复制两个 doubles 非常便宜,可能不值得间接)。

    【讨论】:

    • 您有多余的副本。如果你传入一个副本,你也可以将它用于你需要制作的“副本”。不要使用“this”的值制作另一个新版本……而是使用“other”作为副本。你是对的,2 双打几乎不算什么,但如果你这样做数百万次,它就会加起来。
    • @ChrisMM:实际上,当可观察到的副作用没有变化并且这一切都发生在一个函数中时,我希望编译器能够忽略这种事情。无论您执行多少次,我都不希望在这里看到任何性能。但你是对的,其他方法会更整洁。我故意避免更改与函数参数相关的任何内容(如最后一段中所述),但可能忽略了它太多
    • @ChrisMM 我已经编辑了答案来讨论这个问题。不过,不认为​​它真的值得投反对票吗?
    • 是的,编辑使页面引起了更多人的注意,他们认为这个答案应该被否决,而无代码转储解释的替代方案应该得到更多的选票。喜欢这个网站。
    • @ChrisMM Here's a demo 表明两种情况下的程序集是相同的(&screenshot for posterity)。这并不奇怪。这些程序实际上做同样的事情。 “优化编译器”构建按照您的源代码描述的程序;他们不只是将 C++ 的每一行逐字逐句转换成一些汇编指令。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-28
    • 2013-01-24
    • 1970-01-01
    • 2021-01-10
    • 1970-01-01
    • 2014-10-01
    • 1970-01-01
    相关资源
    最近更新 更多