修复过载而不中断客户端

问题描述 投票:0回答:1

这里是我目前正在研究的玩具的一个例子

class Foo
{
   private:
     std::string s;
     std::vector<std::string> v;
   public:

      // Foo constructors and other big 3

      std::string const& strmember() const;
      std::vector<std::string> const& vecmember() const;
      std::vector<std::string>& vecmember();
};

到目前为止一切都很好。要求是这样的,我必须添加重载并更改Foo的内线,如下所示

class Foo
{
   private:
     std::u16string ssname;
     std::vector<std::u16string> vvname;
   public:

      // Foo constructors and other big 3

      std::string const& strmember() const;
      std::vector<std::string> const& vecmember() const;
      std::vector<std::string>& vecmember();

      std::u16string const& strmember(int) const;
      std::vector<std::u16string> const& vecmember(int) const;
      std::vector<std::u16string>& vecmember(int);
};

我必须保留旧成员并为新成员添加重载,以使旧客户端不会中断。执行适当的字符转换,以便将较早的构造函数委派给新的构造函数,并根据新设计更改提供的成员。

如下实施这些成员

std::string const& Foo::strmember() const
{
    const auto& name = char_convert(ssname);
    return name; 
}
std::vector<std::string>& Foo::vecmember()
{
    return vecmember();
} 
std::vector<std::string>& Foo::vecmember()
{
    std::vector<std::string> result;
    std::transform(vvname.begin(),vvname.end(),std::back_inserter(result),[] (const std:u16string& in) -> std::string
                                                            {
                                                                return char_convert(in);
                                                            });
    return result;
}

std::u16string const& Foo::strmember(int) const
{
    return ssname;
}

std::vector<std::u16string> const& Foo::vecmember(int) const
{
    return vvname;
}

std::vector<std::u16string>& Foo::vecmember(int)
{
    return vvname;
}

[当我尝试编译更改的代码时,编译器会显示以下警告和错误消息

error: reference to local variable ‘result’ returned [-Werror=return-local-addr]
     std::vector<std::string> result;
                              ^~~~~~
foo.cpp: In member function ‘const string& foo::strmember() const’:
foo.cpp: error: function returns address of local variable [-Werror=return-local-addr]
     return name;
            ^~~~
foo.cpp: note: declared here
     const auto& name = char_convert(ssname);
                                                 ^
cc1plus: all warnings being treated as errors

我该如何解决这个问题?我无法更改界面,因为它可能会破坏单元测试和客户端。

我如何提供vecmember()strmember()函数的转换器和访问器版本?

c++ c++11 g++
1个回答
0
投票
我想强调另一个相同类型的问题。当你写:

const auto& name = char_convert(ssname); // Really bad (undefined behaviour)

您正在将引用绑定到右值。该语句之后将销毁std::string返回的临时char_convert()。因此,甚至在name函数返回strmember()之前,它们都是悬空的。您可能应该改写(复制初始化):

auto name = char_convert(ssname); // Better

关于返回对局部变量的const引用的函数,您应该按值返回而不是修复错误(编译器将能够在需要时对返回的局部变量执行复制删除)。

关于最后一个返回非const引用的函数,我认为使用代理类可能会过大(不过,这当然取决于您的用例)。一种更简单的方法可能是编写一个似乎需要的

setter函数。

但是,无论您编写setter还是使用代理,由于它是错误的并调用未定义的行为,因此将破坏与旧代码的兼容性。

© www.soinside.com 2019 - 2024. All rights reserved.