質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

ドメイン駆動設計

ドメイン駆動設計(Domain-driven design, DDD)とは、ソフトウェアの設計手法、および設計思想や哲学のことです。ドメインモデル構築の際に、設計上の判断を決定する枠組みとドメイン設計に関して議論するボキャブラリを提供するものです。

Q&A

解決済

1回答

1637閲覧

C#のas演算子をC++で実装したい

ladybug_10

総合スコア3

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

ドメイン駆動設計

ドメイン駆動設計(Domain-driven design, DDD)とは、ソフトウェアの設計手法、および設計思想や哲学のことです。ドメインモデル構築の際に、設計上の判断を決定する枠組みとドメイン設計に関して議論するボキャブラリを提供するものです。

0グッド

0クリップ

投稿2020/11/09 12:32

前提・実現したいこと

リンク先を参考に、ドメイン駆動設計で用いられるValueObjectをC#で実装しました。

csharp

1// ValueObjectクラス 2public abstract class ValueObject<T> where T : ValueObject<T> { 3 public override bool Equals(object obj) { 4 var vo = obj as T; 5 if (vo == null) { 6 return false; 7 } 8 9 return EqualsCore(vo); 10 } 11 12 public static bool operator ==(ValueObject<T> vo1, 13 ValueObject<T> vo2) { 14 return vo1.Equals(vo2); 15 } 16 17 public static bool operator !=(ValueObject<T> vo1, 18 ValueObject<T> vo2) { 19 return !(vo1 == vo2); 20 } 21 22 protected abstract bool EqualsCore(T other); 23} 24 25 26// ValueObjectクラスを用いたCityクラス 27public sealed class City : ValueObject<City> { 28 public string Name { get; } 29 30 public City(string name) { 31 Name = name; 32 } 33 34 protected override bool EqualsCore(City other) { 35 return Name == other.Name; 36 } 37}

 
現在、このValueObjectをC++で実装しようと試みています。実装したコードは下記になります。

cpp

1#include <type_traits> 2 3 4template<class T> 5class ValueObject { 6 7public: 8 ValueObject() { 9 static_assert(std::is_base_of<ValueObject<T>, T>::value, "T must inherit from ValueObject<T>"); 10 } 11 12 virtual ~ValueObject() {}; 13 14 bool Equals(const ValueObject<T>& other) { 15 auto vo = dynamic_cast<T*>(&other); 16 if (vo == nullptr) { 17 return false; 18 } 19 return EqualsCore(other); 20 } 21 22 bool operator== (const ValueObject<T>& other) { 23 return this->Equals(other); 24 } 25 26 bool operator!= (const ValueObject<T>& other) { 27 return !(this == (other)); 28 } 29 30protected: 31 virtual bool EqualsCore(const T& other) = 0; 32}; 33 34 35class City final : public ValueObject<City> { 36public: 37 std::string name_; 38 39 City(const std::string& name) { 40 name_ = name; 41 } 42 43 ~City(){}; 44 45protected: 46 bool EqualsCore(const City& other) override { 47 return name_ == other.name_; 48 } 49}; 50 51 52int main() { 53 City c1("東京"); 54 City c2("神奈川"); 55 City c3("神奈川"); 56 c1 == c2; 57 c2 == c3; 58}

発生している問題・エラーメッセージ

コンパイルすると、以下のようなエラーメッセージが表示されます。

'dynamic_cast' を使用して 'const ValueObject<City> *' から 'T *' に変換することはできません。 'vo': 初期化前に使用することはできません '==': 'nullptr' 型から 'int' 型への変換ができません。

エラーに該当している箇所は、Equals関数内のキャスト部分になります。
これは、テンプレートクラスを用いているためにおこるエラーでしょうか。
C#のas演算子をC++で実装するにあたって、このようなダイナミックキャストを用いた方法を採用したのですが、そのほかに良い実装案があれば、ご教示いただきたいです。

環境

OS:Windows10 Home 64bit
C++バージョン:C++14
IDE:Visual Studio 2019 Community

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ladybug_10

2020/11/10 10:46

こんな便利なツールがあったとは知りませんでした。ありがとうございます。
guest

回答1

0

ベストアンサー

C++ 方式のキャストは四つありますがそれぞれの役割があり、役割の他のことは出来ません。 dynamic_castconst を外すことは出来ないのです。

この場合は const を外す意味はありませんから dynamic_cast<const T*>(&other); といったように const 付きの型に変換してください。 その他にもちょっとした間違いはあるようですが、それはエラーメッセージを見れば直せるでしょう。

投稿2020/11/09 13:14

SaitoAtsushi

総合スコア5684

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ladybug_10

2020/11/10 10:48

constをキャストする型に含めて、その他微修正したところ、コンパイルできました。キャストする型にはconstも含めないといけないのですね。ご回答ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問