【问题标题】:Assigning base class object to derived class object将基类对象分配给派生类对象
【发布时间】:2015-01-14 18:16:23
【问题描述】:
    class Base{};
    class Derived: public Base{};

    int main()
    {
        Base B;
        Derived D;

        Base B1 = D;//OK
        Derived D1 = B;//error: conversion from ‘Base’ to non-scalar 
                       //type ‘Derived’ requested
        return 1;
    }

我知道派生类与基类有 is-a 关系。

什么阻止 Derived D1 具有来自 B 的值和具有一些垃圾值的剩余成员变量(如果有)?

或者

错误信息是什么

请求从“Base”转换为非标量类型“Derived” Derived D1 = B;

说?什么是标量类型?

【问题讨论】:

  • 您可以添加构造函数Derived(const Base&) 来提供转换
  • “is-a”关系只适用于一个方向。
  • 好的,但我的问题是,为什么不默认。
  • 答案就在问题中。垃圾值。
  • 这不是一模一样的副本,之前的问题是关于复制分配的,没有人谈论初始化。

标签: c++ inheritance


【解决方案1】:

声明

Derived D1 = B;

是一个初始化,而不是一个赋值(即使它看起来像一个赋值)。

它尝试使用Derived 复制构造函数,但该复制构造函数需要一个参数Derived const&。并且B 实例无法自动转换为完整的Derived

如果你真的想要一个切片分配——只分配给D1Base切片——那么你可以显式地使用Base::operator=

Derived D1;
D1.Base::operator=( B );

另一种表达方式:

Derived D1;
static_cast<Base&>( D1 ) = B;

但它闻起来很臭。 ;-)


回复

什么是标量类型?

这与“规模”中的词相同。标量类型提供单个幅度值,因此该类型的值可以与==(理想情况下也可以与&lt;)进行比较。但是,在 C++ 中,指针甚至成员指针都被视为标量类型:

C++11 §3.9/9 [basic.types]:

算术类型 (3.9.1)、枚举类型、指针类型、指向成员类型的指针 (3.9.2)、std::nullptr_t 和这些类型的 cv 限定版本 (3.9 .3) 统称为标量类型

【讨论】:

    【解决方案2】:

    如果B 的成员变量被声明为私有,那么这将阻止D1 拥有B 的值。

    至于您的第二个问题,您可以分配Base B1 = D;,因为编译器知道DB 的派生类。但是,在Derived D1 = B; 中,编译器没有表明这种关系。

    关于什么是标量的问题,标量是整数、字符、指针等。它们不同于结构和类,它们是用户定义的类型。

    【讨论】:

      猜你喜欢
      • 2018-02-02
      • 2015-11-07
      • 2012-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-13
      • 1970-01-01
      • 2016-08-20
      相关资源
      最近更新 更多