我可以使用虚拟类函数,但在类定义之外指定它们吗?

时间:2016-06-17 19:02:05

标签: class c++11 inheritance header-files virtual-functions

我不知道这是否可行,或者是否应该这样做。在使用具有虚函数的基类时,我可以严格保持我的.hpp文件接口而不包含源吗?这是学习/测试代码,我想改变这种方式工作。 Address是继承到EmailAddress和WebAddress类的基类。

address.cpp:

#include <string>
#include "address.hpp"

address.hpp:

#include <string>

#ifndef ADDRESS_HPP_
#define ADDRESS_HPP_

class Address {
public:
    virtual ~Address(){}
    virtual std::string to_string() const = 0;
};

#endif // ADDRESS_HPP_

emailaddress.cpp:

#include <string>
#include "emailaddress.hpp"
#include "address.hpp"

EmailAddress::EmailAddress(const EmailAddress& rhs) : _email(rhs._email) {}
EmailAddress::EmailAddress(std::string e) : _email(e) {}
EmailAddress& EmailAddress::operator=(const EmailAddress& rhs){
    if (&rhs != this) {
        _email = rhs._email;
    }
    return *this;
}

emailaddress.hpp:

#include <string>
#include "address.hpp"

#ifndef EMAILADDRESS_HPP_
#define EMAILADDRESS_HPP_

class EmailAddress : public Address {
public:
    EmailAddress() {}
    EmailAddress(const EmailAddress&);
    EmailAddress(std::string);
    virtual ~EmailAddress(){}
    EmailAddress& operator=(const EmailAddress&);
    std::string to_string() const override { return _email; }
private:
    std::string _email;
};
#endif // EMAILADDRESS_HPP_

webaddress.cpp:

#include <string>
#include "webaddress.hpp"
#include "address.hpp"

WebAddress::WebAddress(const WebAddress& rhs) : _uri(rhs._uri) {}
WebAddress::WebAddress(std::string e) : _uri(e) {}
WebAddress& WebAddress::operator=(const WebAddress& rhs){
    if (&rhs != this) {
        _uri = rhs._uri;
    }
    return *this;
}

webaddress.hpp:

#include <string>
#include "address.hpp"

#ifndef WEBADDRESS_HPP_
#define WEBADDRESS_HPP_

class WebAddress : public Address {
public:
    WebAddress() {}
    WebAddress(const WebAddress&);
    WebAddress(std::string);
    virtual ~WebAddress(){}
    WebAddress& operator=(const WebAddress&);
    std::string to_string() const override { return _uri; }
private:
    std::string _uri;
};

#endif // WEBADDRESS_HPP_

main.cpp中:

#include <string>
#include <memory>
#include <iostream>
#include "address.hpp"
#include "emailaddress.hpp"
#include "webaddress.hpp"

void print_address(std::shared_ptr<Address> a) {
    std::cout << "address: " << a->to_string() << std::endl;
}

int main(int argc, char* argv[]) {
    std::shared_ptr<Address> s(new WebAddress("www.google.com"));
    print_address(s);

    std::shared_ptr<Address> s2(s);
    print_address(s2);

    std::shared_ptr<Address> s3 = s;
    print_address(s3);

    s.reset(new EmailAddress("john.doe@gmail.com"));
    print_address(s);

    s2.reset(new EmailAddress("john.doe@gmail.com"));
    print_address(s2);

    s3 = s;
    print_address(s3);

    return 0;
}

2 个答案:

答案 0 :(得分:2)

  

在使用具有虚函数的基类时,我可以严格保持我的.hpp文件接口而不包含源吗?

是的,您可以将虚函数的声明和定义分为标题和实现文件。

答案 1 :(得分:0)

这样做似乎有效。之前让我感到困惑的是虚拟说明符“覆盖”在类定义之外并被放置在.cpp文件中。以下是现在似乎有效的更新emailaddress文件:

<强> emailaddress.hpp

#include <string>
#include "address.hpp"

#ifndef EMAILADDRESS_HPP_
#define EMAILADDRESS_HPP_

class EmailAddress : public Address {
public:
    EmailAddress() {}
    EmailAddress(const EmailAddress&);
    EmailAddress(std::string);
    virtual ~EmailAddress(){}
    EmailAddress& operator=(const EmailAddress&);
    std::string to_string() const override;
private:
    std::string _email;
};
#endif // EMAILADDRESS_HPP_

<强> emailaddress.cpp

#include <string>
#include "emailaddress.hpp"
#include "address.hpp"

EmailAddress::EmailAddress(const EmailAddress& rhs) : _email(rhs._email) {}
EmailAddress::EmailAddress(std::string e) : _email(e) {}
EmailAddress& EmailAddress::operator=(const EmailAddress& rhs){
    if (&rhs != this) {
        _email = rhs._email;
    }
    return *this;
}
std::string EmailAddress::to_string() const { return _email; }