2016-06-17 2 views
-2

Я не знаю, возможно ли это или даже если это нужно сделать. Могу ли я хранить файлы в формате .hpp строго без использования источника при использовании базового класса с виртуальными функциями? Вот код обучения/теста, который я бы хотел изменить, чтобы работать таким образом. Адрес - это базовый класс с наследованием в классы 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("[email protected]")); 
    print_address(s); 

    s2.reset(new EmailAddress("[email protected]")); 
    print_address(s2); 

    s3 = s; 
    print_address(s3); 

    return 0; 
} 
+1

В чем проблема? Единственными объявленными виртуальными функциями являются dtors, но вы их никогда не реализовывали ... –

+0

Хороший вопрос. Я использую онлайн-видеоурок, и dtors даже не упоминается. Он потерял меня с тех пор, как я попытался изменить пример hpp-файлов, чтобы не включать исходный код. – mszlazak

+0

Файл address.hpp представляется случайной копией webaddress.cpp. Я подозреваю, что вопрос станет более понятным для нас, если вы включите свой фактический файл address.hpp. (Я предполагаю, что это некоторые из ваших виртуальных объявлений). –

ответ

2

Могу ли я хранить файлы в формате .hpp строго без использования источника при использовании базового класса с виртуальными функциями?

Да, вы можете отделить декларацию и определение виртуальных функций в файлы заголовка и реализации.

+0

Не могли бы вы показать мне, как я не могу заставить его работать. – mszlazak

+0

Большинство C++-кода делают это именно так. Поэтому загрузите любое бесплатное программное обеспечение на C++, например. из [github] (http://github.com/) и заглянуть внутрь его исходного кода. –

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; }