2016-06-17 6 views
-2

これが可能かどうか、それを行うべきかどうかはわかりません。仮想関数を持つ基底クラスを使用するときに、ソースを含まずに私の.hppファイルを厳密にインターフェースしておくことはできますか?このように動作するように変更したい学習/テストコードをここに示します。 Addressは、クラスEmailAddressおよびWebAddressに継承される基本クラスです。私は仮想クラス関数を使用することができますが、クラス定義の外にそれらを指定できますか?

address.cpp:

​​

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に:

仮想関数を持つ基本クラスを使用するときに3210
#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; } 
関連する問題