Реализация оператора Deduplicate

У меня такой рабочий код:

person.h

#ifndef PERSON_H
#define PERSON_H

#include <iostream>
#include <string>

class Person {
private:
    std::string firstName;
    std::string middleName;
    std::string lastName;

public:
    Person() = default;
    Person (std::string pFirstName, std::string pMiddleName, std::string pLastName);
    Person (std::string pFirstName, std::string pLastName);

    std::string getFirstName();
    void setFirstName(std::string pFirstName);
    std::string getLastName() const;
    void setLastName(std::string pLastName);
    std::string toString() const;

    friend std::ostream& operator<<(std::ostream& target, Person const & person);
};

#endif

person.cpp

#ifndef __person__
#define __person__

#include <iostream>
#include <string>

#include "person.h"

using std::string;
using std::ostream;

Person::Person (string pFirstName, string pMiddleName, string pLastName)
: firstName(pFirstName), middleName(pMiddleName), lastName(pLastName)
{
}

Person::Person (string pFirstName, string pLastName)
: firstName(pFirstName), middleName(""), lastName(pLastName)
{
}

string Person::getFirstName ()
{
    return firstName;
}

void Person::setFirstName (string pFirstName)
{
    firstName = pFirstName;
}

string Person::getLastName () const
{
    return lastName;
}

void Person::setLastName (string pLastName)
{
    lastName = pLastName;
}

string Person::toString () const
{
    if (middleName == "")
        return firstName + " " + lastName;

    return firstName + " " + middleName + " " + lastName;
}

ostream& operator<< (ostream& target, Person const & source)
{
    target << source.toString();
    return target;
}

#endif

tweeter.h

#ifndef TWEETER_H
#define TWEETER_H

#include <string>

#include "person.h"

class Tweeter
: public Person
{
private:
    static int gid;
    int id;
    std::string twitterHandle;

public:
    Tweeter(std::string pFirstName, std::string pMiddleName, std::string pLastName, std::string pTwitterHandle);
    Tweeter(std::string pFirstName, std::string pLastName, std::string pTwitterHandle);
    std::string toString() const;
    friend std::ostream& operator<< (std::ostream& target, Tweeter const & source);
};

#endif

tweeter.cpp

#ifndef __tweeter__
#define __tweeter__

#include <iostream>

#include "tweeter.h"

using std::ostream;
using std::string;
using std::to_string;

int Tweeter::gid = 0;

Tweeter::Tweeter(string pFirstName, string pMiddleName, string pLastName, string pTwitterHandle)
: Person(pFirstName, pMiddleName, pLastName), id(gid), twitterHandle(pTwitterHandle)
{
    gid++;
}

Tweeter::Tweeter(string pFirstName, string pLastName, string pTwitterHandle)
: Tweeter(pFirstName, "", pLastName, pTwitterHandle)
{
}

string Tweeter::toString() const
{
    return "[" + to_string(id) + "] " + Person::toString() + " (" + twitterHandle + ")";
}

ostream& operator<< (ostream& target, Tweeter const & source)
{
    target << source.toString();
    return target;
}

#endif

Как видите, у меня есть почти дублирующая реализация для << оператор в подклассе Tweeter. Я должен был это сделать, поскольку, если я просто использую << реализация оператора унаследована от Person, C ++ незаметно приводил Tweeter экземпляр как Person согласно подписи и вызову операторской функции Person::tostring() вместо Tweeter::toString(). Возможно ли иметь только одну реализацию << оператор, который может быть унаследован без переопределения и, следовательно, дублирования кода?

1 ответ
1

Да используйте виртуальный print() функция.

PS. Я бы также сделал toString используйте функцию виртуальной печати, чтобы сделать ее более эффективной.

class Person 
{
    // OTHER STUFF

    virtual void print(std::ostream& target = std::cout) const
    {
        target << firstName << " ";
        if (middleName != "") {
            target << middleName << " ";
        } 
        target << lastName;
    }
    std::string toString() const
    {
        std::stringstream  stream;
        this->print(str);
        return stream.str();
    }

    friend std::ostream& operator<<(std::ostream& target, Person const& person)
    {
        person.print(target);
        return target;
    }
};


class Tweeter: public Person
{
    // OTHER STUFF


    // Don't need this any more: => std::string toString() const;
    // Don't need this any more: => friend std::ostream& operator<< (std::ostream& target, Tweeter const & source);

    virtual void print(std::ostream& target = std::cout) const override
    {
         target << "[" << to_string(id) << "] ";
         Person::print(target);
         target <<  " (" << twitterHandle << ")";
    }
};

  • Спасибо. С toString() был только помощником для << На самом деле мне это больше не нужно после введения виртуального print() функции.

    — Ричард Нойманн


Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *