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

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

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

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

Q&A

解決済

3回答

1142閲覧

C++ operator=(char* p)で警告が出る

退会済みユーザー

退会済みユーザー

総合スコア0

C++

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

0グッド

0クリップ

投稿2021/08/03 05:22

中学校でコンピュータ部に所属している者です。

JavaやC#の様なstring型をC++で実現しようとstrクラスを作っているのですが,
g++でコンパイルする度に警告がでます。
以下にコードを示します。

C++

1//C:\DEV\str.h 2 3#include <cstring> 4 5class str { 6 public : 7 ~str(); 8 str& operator=(char *p); 9 //+= , + , 等価演算子・比較演算子は後で実装 10 //private : //一時的にコメントアウト 11 char *pstr = 0; 12}; 13 14str::~str() { if(this->pstr != 0) { delete[] this->pstr; } } 15 16str& str::operator=(char *p) 17{ 18 unsigned int count = std::strlen(p); 19 20 if(this->pstr != 0) { delete[] this->pstr; } 21 this->pstr = new char[count]; 22 while(count != 0) 23 { 24 this->pstr[count] = *(p + count); 25 count--; 26 } 27 this->pstr[0] = *p; 28 29 return *this; 30} 31

C++

1//C:\DEV\test.cpp 2#include <cstdio> 3#include "str.h" 4 5int main() 6{ 7 str s; 8 s = "This is test."; 9 std::puts(s.pstr); 10 11 return 0; 12}

コンパイル

c: cd \DEV g++ test.cpp

結果

test.cpp: In function 'int main()': test.cpp:7:6: warning: ISO C++ forbits converting a string constant to 'char*' [-Wwrite-strings] s = "This is test."; ^^^^^^^^^^^^^^^

環境

OS:Windows10 Home 64bit
コンパイラ:MinGW-W64

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

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

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

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

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

episteme

2021/08/03 14:56

[別件] ヘッダに(メンバ関数の)定義を置いちゃダメ!
guest

回答3

0

str& str::operator=(char *p)

str& str::operator=(const char *p)

警告なので無視できますが...
いわゆるキャストが曖昧で、コンパイラからしかられているだけです。
本来C++言語では、const char*からchar *への変換はコンパイルエラーとして扱われるます。
しかし、C言語では「文字列リテラル(const char配列)からchar *への自動変換を特別に許可」されています。
C++言語でも歴史的経緯(C言語が親)として、互換性の意味合いで自動変換(キャスト)を許容するします。(警告付き)

投稿2021/08/03 05:53

編集2021/08/03 09:18
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

operator=(char* p)

"This is test." を引数にとるには
operator=( const char* p ) たるべき,という話かと.

投稿2021/08/03 05:29

fana

総合スコア11654

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

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

0

ベストアンサー

文字列リテラルは書き換えできないので、

cpp

1 str& operator=(char *p);

char* ではなく const char* にしましょう。

投稿2021/08/03 05:31

int32_t

総合スコア20832

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

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

退会済みユーザー

退会済みユーザー

2021/08/03 05:38

const指定したら警告が出なくなりました! ありがとうございます
SaitoAtsushi

2021/08/03 06:31

余談ですが C++03 までは文字列リテラルを char* へ暗黙に型変換することは許されていました。 (C++03 の時点でも非推奨ではありましたので g++ は警告を出していましたが forbits converting ではなく deprecated conversion というメッセージでした。) そういう事情もあって古い資料では文字列の const の有無に無頓着な場合があり、そのコードのままだと新しい仕様に合致しないということもあります。 C++ は基本的には大きく互換性を損なわないように改定されていますが、特に問題のある部分は非推奨にした上でさらに後の改定で廃止するということも少しはあるので、読む資料の選択においてはその資料がいつの時代に書かれたものか、いつの仕様を根拠としたものかというのは気にしておくとよいでしょう。
fana

2021/08/03 07:40

型変換の可否がどうのいう話があろうがなかろうが このoperatorはポインタが指す場所を変更しないのだから引数はconstにすべきところだと思う.
SaitoAtsushi

2021/08/03 07:56

「すべき」という点ではその通りです。 ですがそうなっていない資料が存在するので気を付けろという意図です。
退会済みユーザー

退会済みユーザー

2021/08/03 11:39

str型を完成させたのですが・・・ もしパラメータをstr型とする関数funcを宣言したとして, func("test"); みたいな呼び出しはエラーになりますよね? これって解決できるんですか?
SaitoAtsushi

2021/08/03 14:50

const char * を引数とするコンストラクタを定義してください。 関数の仮引数と実引数の関係は変数の初期化のメカニズムに対応します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問