chaoren00001 2019-01-23 22:38 采纳率: 100%
浏览 646
已采纳

C++中私有继承的派生类,如何对继承来的子对象使用赋值运算符?

本人新手,做书上的练习题遇到的麻烦。

问题背景:
要操作的是一个多重继承的派生类Wine,分别私有继承了一个标准string类和一个模板类Pair< T1,T2>,
其中T1、T2均具体化为std::valarray< int>,代码如下

// 模板类(作为基类)的定义
template <class T1, class T2>
class Pair {
private:
    T1 a;
    T2 b;
public:
    ...
    T1 & first() { return a; }
    T2 & second() { return b; }
    T1 first() const { return a; }
    T2 second() const { return b; }
    Pair & operator=(Pair & rp);
};
template < class T1, class T2 >
Pair<T1, T2> & Pair<T1, T2>::operator=(Pair<T1, T2> & rp) {
    a = rp.first();
    b = rp.second();
    return *this;
}

// 派生类的定义
typedef std::valarray<int> ArrayInt;
typedef Pair<ArrayInt, ArrayInt> PairArray;

class Wine : private string,private PairArray {
private:
    int years;
public:
    Wine(const char *lab, int y, int yr[], const int bot[]);
    // 字符串lab填充继承来的string子对象,y填充years,
    // yr[] 和 bot[] 都转换成ArrayInt,用来填充继承来的 Pair<ArrayInt, ArrayInt>
    ...
};

我的问题:

问题1:Wine的构造函数中可以对Pair< ArrayInt, ArrayInt>的两个ArrayInt对象分别赋值,但是为什么对Pair< ArrayInt, ArrayInt>作为一个整体的对象不能这么做?

Wine::Wine(const char *l, int y, int yr[], const int bot[]) : string(l), years(y) {
    ArrayInt yr_temp(years), bot_temp(years);
    for (int i = 0; i < years; i++) {
        yr_temp[i] = yr[i];
        bot_temp[i] = bot[i];
    }
    (*((PairArray*)this)).first() = yr_temp;    // ok
    (*((PairArray*)this)).second() = bot_temp;  // ok
}

Wine::Wine(const char *l, int y, int yr[], const int bot[]) : string(l), years(y) {
    ArrayInt yr_temp(years), bot_temp(years);
    for (int i = 0; i < years; i++) {
        yr_temp[i] = yr[i];
        bot_temp[i] = bot[i];
    }
    (*((PairArray*)this)) = Pair(yr_temp, bot_temp);  // invalid
}

图片说明

(问题1的图片)

问题2:为什么必须用(*((PairArray*)this))而不能用(PairArray &)(*this),这两者有什么不同吗?

问题2的图片:

图片说明

本人C++后进,若有前辈能不吝点拨一二,感激不尽

  • 写回答

1条回答 默认 最新

  • chaoren00001 2019-02-14 20:53
    关注

    经深入看书,试对此问题自行回答。

    问题一:Wine的构造函数中可以对Pair< ArrayInt, ArrayInt>的两个ArrayInt对象分别赋值,但是为什么对Pair< ArrayInt, ArrayInt>作为一个整体的对象不能这么做?
    答:示例代码中先定义了两个ArrayInt对象的临时变量作为左值,并将它们作为参数分别对Pair<>的first()和second()进行复制赋值,所以可以通过。
    而(*((PairArray*)this)) = Pair(yr_temp, bot_temp); // invalid 这条语句赋值符号右边是函数返回值,是一个右值,但Pair<>没有定义移动赋值运算符,所以不通过编译。
    解决方案有两个:要么定义移动语义版本的赋值运算符和构造函数,要么显式定义一个变量(左值)temp_val存储此右值,然后用temp_val作为相应的函数参数

    问题2的答案就在图示的编译器错位提示里。。。。。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 用visualstudio2022创建vue项目后无法启动
  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
  • ¥500 把面具戴到人脸上,请大家贡献智慧
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急
  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error
  • ¥15 VS2022+WDK驱动开发环境
  • ¥30 关于#java#的问题,请各位专家解答!
  • ¥30 vue+element根据数据循环生成多个table,如何实现最后一列 平均分合并