🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
MFC

MFC (Microsoft Fouondation Class)とは、MicrosoftがVC++用に開発したWindows用アプリケーションのフレームワークです。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

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

Q&A

解決済

1回答

3067閲覧

クラスの変数を引数で渡した時の動作について

oppeke

総合スコア11

MFC

MFC (Microsoft Fouondation Class)とは、MicrosoftがVC++用に開発したWindows用アプリケーションのフレームワークです。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

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

0グッド

1クリップ

投稿2021/01/27 09:49

お世話になっております。
C++のクラスについて、クラスの変数を引数で渡した際の動作について、ご質問があります。

MFC(ATL?)には文字列を扱う為のクラス"CString"があります。
このクラスを、引数がconst char*型やLPCSTRなどの関数に渡しても正常に動作します。
例としては、printfやfputsやMessageBoxなど関数になります(ごく一部)
CString型の変数を渡しているのに、何故、型が異なる等のコンパイルエラーが発生しないのか、疑問に思いました。

CStringで内部的にはchar型で文字列の情報を保存しており、引数の場合にはchar型として
返すような仕様になっているのだとは予想しているですが、実際にはどういう技術を使用して、実装しているのでしょうか?

operatorの機能などで、引数の場合など書き方があるのかな?と思い、
「operator 引数」などで調べましたが、関係のありあそうな情報は見つかりませんでした。
(勝手なイメージ)
operator 引数の場合(){
return メンバ変数;
}
(そもそもoperatorは演算子のオーバーロードなので、絶対違いますよね…)

例として使用したソースは以下になります。

C++

1#include <stdio.h> 2#include <string.h> 3#include <atlstr.h> // CString用 4 5class CTestStr 6{ 7public: 8 CTestStr(char* _str) 9 { 10 strcpy_s(str, sizeof(str), _str); 11 } 12 ~CTestStr(void){}; 13 14private: 15 char str[256]; 16 17}; 18 19int main(void) 20{ 21 CString str1 = "テスト1"; 22 CTestStr str2("テスト2"); 23 24 printf("%s\n", str1); // テスト1 表示される 25 //printf("%s\n", str2); // 上と同じように表示出来る??? 26 27 return 0; 28}

テストのコードなので、超適当ですがご容赦お願いします。
CStringと同じ方法を使用すれば、CTestStrクラスでも同じようにprintfで文字列を表示等が出来るんだと思います。
文字列以外でも色々と応用できると思うので、CStringがどうやってこの仕組みを実装しているのか、ご教授いただけないでしょうか?

御手数をお掛け致しますが、宜しくお願い致します。

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

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

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

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

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

guest

回答1

0

ベストアンサー

引数がconst char*型やLPCSTRなどの関数に渡しても正常に動作するのは、
const char*LPCSTRへのキャスト演算子が定義されているからですね。
CSimpleStringT:: operator PCXSTR

CStringの実体がCStringTで、CStringTCSimpleStringTを継承している

printfに直接CStringを渡した場合については、正式には動作すると保証されているわけではありません。
最新のVisual Studio 2019 Communityでビルドすると警告が出ますし、
上記のリンク先でも、printfに渡す際には事前にキャストするように書かれています。

それでも動作する理由については、こちらを参照してください。
How can CString be passed to format string %s?

上記リンク先によると、CStringと同じレイアウト(char*型のメンバ変数1つのみ)であれば、
printfに直接渡して動作するようです。
ただ、いつまでこの動作が保証されるかは未知数ですので、この動作に依存するのはお勧めできません。

c++

1#include <stdio.h> 2#include <string.h> 3#include <atlstr.h> // CString用 4 5class CTestStr 6{ 7public: 8 CTestStr(const char* _str) 9 { 10 str = new char[256]; 11 strcpy_s(str, 256, _str); 12 } 13 ~CTestStr(void) { delete[] str; }; 14 operator LPCSTR() { return str; } 15 16private: 17 char* str; 18 19}; 20 21int main(void) 22{ 23 CString str1 = "テスト1"; 24 CTestStr str2("テスト2"); 25 26 fputs(str1, stdout); 27 printf("%s\n", str1); // テスト1 表示される 28 fputs(str2, stdout); 29 printf("%s\n", str2); // 上と同じように表示出来る??? 30 31 return 0; 32}

投稿2021/01/27 09:59

編集2021/01/27 20:58
actorbug

総合スコア2429

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

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

oppeke

2021/01/28 00:13

ご回答ありがとうございました! 動作する理由について、理解することができました。 正式に動作が保障されれている訳では無かったのですね。。。 参考リンクまで貼っていただき、ありがとうございます(2つ目のリンクの方は、完全に理解できたわけではないので、もう少し読んでみます)。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問