繁体   English   中英

为什么我不能在派生的 class 运算符>>中调用基本 class 运算符>>?

[英]Why i can't call base class operator>> in derived class operator>>?

假设我们有 2 个类:

class base{

protected:
    char first_name;
public: 
    /// constructors , destructor, operator= overloading ...
    
    friend istream& operator >> (istream& in, base &client1) 
    {
        char f_name[1001];
        cout << "First Name: ";
        in >> f_name;
        client1=base(f_name); /// class parameterised constructor;
         
        return in;
    }
};

class derived: public base{

protected:
    char last_name[1001];
public: 
    /// constructors , destructor, operator= overloading ...
    
    friend istream& operator >> (istream& in, derived &client2) 
    {
        char l_name[1001], f_name[1001];
       
        in >> (base) client2; /// it's not working like it dose in operator<<..
        cout << "Last Name: ";
        is >> l_name;
        client2=derived(f_name, l_name); /// class parameterized constructor, 2 parameters because it use base constructor as well;
         
        return in;
    }
};

我重载了一些 output 运算符(<<),每次我从派生运算符 << 中的 base 调用运算符 << 时似乎都很好。

我不知道这是否适用于 operator<<,我尝试了一些方法,但它给出了一个错误。 当我在派生的 class 运算符内调用基本 class 运算符>>它给我错误:

" 没有匹配的 function 用于调用 'operator>>(std::istream&, abonament)'|"

同样,如果我在 operator<< 中做同样的事情,它工作正常:

friend ostream& operator << (ostream& out, derived &client) 
    {
       
        out << (base) client; /// it's working;
       
        out << client.last_name;
         
        return in;
    }

是否可以在派生的 class 运算符中调用基本 class 运算符>> > 为什么会发生这种情况以及如何解决? (我希望我不必在派生的 class 运算符中再次重写基本 class 运算符>>中的相同行>>)

您已成为object 切片的牺牲品。 您可以通过转换为参考来解决眼前的问题。

in >> (base) client2;

真正发生的是一个新的临时Base是由client2制成的,丢弃了所有derived的添加成员。 这是合法的。 编译器感到不安,因为临时Base不能用作base &client1参数的参数。 临时变量就像听起来一样。 它们的时间不长,所以引用一个是编译器阻止你犯的错误。 如果它是合法的,则临时变量将由Base>>运算符修改,然后立即从 scope 中删除 go,然后您才能使用读入的内容。

in >> (base&) client2;

不切片也不做临时变量。 client2已成功更新。 不幸的是,这项工作在

client2=derived(f_name, l_name);

用未初始化的变量l_name覆盖它。

所以需要更多的改变。

不要使用构造函数来完全重新创建和重新分配您正在读取的对象。 而是直接读入对象的成员变量。

例子:

class base{

protected:
    char first_name[1001]; // need more than one character
public: 
    /// constructors , destructor, operator= overloading ...
    
    friend istream& operator >> (istream& in, base &client1) 
    {
        // char f_name[1001]; don't need. Read into member
        cout << "First Name: ";
        in >> client1.first_name; // read directly into member
        // client1=base(f_name); don't need. Work done above
         
        return in;
    }
};

class derived: public base{

protected:
    char last_name[1001];
public: 
    /// constructors , destructor, operator= overloading ...
    
    friend istream& operator >> (istream& in, derived &client2) 
    {
        //char l_name[1001], f_name[1001]; don't need. Use member variables
       
        in >> (base&) client2; // client was being sliced. explanatory link above
        //         ^ fixed with reference to allow polymorphism                             
        cout << "Last Name: ";
        in >> client2.last_name; // fixed typo. reading directly into member
        // client2=derived(f_name, l_name); don't need. Work done above
         
        return in;
    }
};

旁注:这是对 inheritance 的误用。 这实际上是在说姓名。 它不是。 阅读 Liskov 替换原则,了解有助于确定 inheritance 何时有意义的好规则。 这是一些入门读物: Liskov 替换原则的一个例子是什么?

旁注: >>将一个以空格分隔的标记(一个单词)读入给定的char数组。 这里有两个问题。 最重要的是它不知道什么时候停止。 1001 字符数组只能部分缓解这种情况。 用户需要长时间打字才能溢出缓冲区,但不要怀疑人们这样做是为了好玩或盈利。 改用std::string ,这个问题就消失了。 第二个问题是整个一个词的事情。 这个解析器不能处理像“Billy Bob”或“von Doom”这样的名字,幸运的是这个姓氏的所有者是虚构的,因为众所周知他是无情的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM