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

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

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

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

Q&A

解決済

1回答

10003閲覧

VC++ エラー:削除された関数を参照しようとしています

robomoco

総合スコア31

C++

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

0グッド

0クリップ

投稿2019/05/07 16:45

main.cpp28行目で,Codewriterオブジェクトcodewriter生成時のコンストラクタに,Parserオブジェクトparserを引数にとったところでエラーが出ました。
原因と解決方法が分かりません。

#出力

1>------ ビルド開始: プロジェクト: VM_Inverter, 構成: Debug Win32 ------ 1>Main.cpp 1>c:\users\ken\documents\nand2tetris\projects\07\virtualmachine\vm_inverter\main.cpp(28): error C2280: 'Parser::Parser(const Parser &)': 削除された関数を参照しようとしています 1>c:\users\ken\documents\nand2tetris\projects\07\virtualmachine\vm_inverter\parser.h(31): note: コンパイラが 'Parser::Parser' をここに生成しました。 1>c:\users\ken\documents\nand2tetris\projects\07\virtualmachine\vm_inverter\parser.h(31): note: 'Parser::Parser(const Parser &)': function was implicitly deleted because a データ メンバー invokes a deleted or inaccessible function 'std::basic_ifstream<char,std::char_traits<char>>::basic_ifstream(const std::basic_ifstream<char,std::char_traits<char>> &)' 1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\fstream(944): note: 'std::basic_ifstream<char,std::char_traits<char>>::basic_ifstream(const std::basic_ifstream<char,std::char_traits<char>> &)': 関数は明示的に削除されました 1>プロジェクト "VM_Inverter.vcxproj" のビルドが終了しました -- 失敗。 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========

#main.cpp

C++

1#include <iostream> 2#include "Parser.h" 3#include "CodeWriter.h" 4 5using namespace std; 6 7int main() 8{ 9 Parser parser; 10 parser.advance(); 11 //cout << parser.commandType() << endl; 12 cout << parser.arg1() << endl; 13 14 parser.advance(); 15 //cout << parser.commandType() << endl; 16 cout << parser.arg1() << endl; 17 cout << parser.arg2() << endl; 18 19 parser.advance(); 20 //cout << parser.commandType() << endl; 21 cout << parser.arg1() << endl; 22 23 parser.advance(); 24 //cout << parser.commandType() << endl; 25 cout << parser.arg1() << endl; 26 cout << parser.arg2() << endl; 27 28 CodeWriter codewriter(parser); 29} 30

#Parser.h

c++

1#pragma once 2#include <fstream> 3#include <sstream> 4#include <string> 5#include <iostream> 6 7 8enum comType{ 9 C_ERROR, 10 C_ARITHMATIC, 11 C_PUSH, 12 C_POP, 13 C_LABEL, 14 C_GOTO, 15 C_IF, 16 C_FUNCTION, 17 C_RETURN, 18 C_CALL 19}; 20 21class Parser { 22public: 23 std::string infilename; 24 Parser(); //読みこみファイルを開く 25 void advance(); //次のコマンドを読みこむ 26 comType commandType(); //コマンドのタイプを返す 27 std::string arg1(); //現コマンドの1番目の引数を返す 28 int arg2(); //現コマンドの2番目の引数を返す 29 std::ifstream ifs; 30 std::string curcmd; //現在コマンド 31};

#Parser.cpp

c++

1#include "Parser.h" 2using namespace std; 3//クラスParserの実装 4Parser::Parser() 5{ 6 cin >> infilename; 7 ifs.open(infilename); 8 while(ifs.fail()) { 9 cin >> infilename; 10 ifs.open(infilename); 11 } 12} 13 14void Parser::advance() 15{ 16 getline(ifs, curcmd); 17 18 while (curcmd[0] == ' ') { 19 curcmd.erase(curcmd.begin()+0); 20 } 21 while (curcmd[0] == '\0') { 22 advance(); 23 } 24} 25 26comType Parser::commandType() 27{ 28 29 //cout << curcmd << endl; 30 31 string curcmdope = curcmd; 32 curcmdope = curcmdope.substr(0, curcmd.find(" ")); 33 if (curcmdope == "add" || curcmdope == "sub" || curcmdope == "neg" || 34 curcmdope == "eq" || curcmdope == "qt" || curcmdope == "lt" || 35 curcmdope == "and" || curcmdope == "or" || curcmdope == "not") { 36 37 return C_ARITHMATIC; 38 } 39 else if (curcmdope == "push") { 40 return C_PUSH; 41 } 42 else if (curcmdope == "pop") { 43 return C_POP; 44 } 45 else { 46 return C_ERROR; 47 } 48} 49 50string Parser::arg1() 51{ 52 string curcmdarg1 = curcmd; 53 54 if (commandType() == C_RETURN) { 55 cout << "C_RETURNは呼ぶな" << endl; 56 return curcmd; 57 } 58 else if (commandType() == C_ARITHMATIC) { 59 return curcmd; 60 } 61 else if (commandType() == C_PUSH || commandType() == C_POP) { 62 63 while (curcmdarg1[0] != ' ') { 64 curcmdarg1.erase(curcmdarg1.begin() + 0); 65 } 66 while (curcmdarg1[0] == ' ') { 67 curcmdarg1.erase(curcmdarg1.begin() + 0); 68 } 69 70 curcmdarg1 = curcmdarg1.substr(0, curcmdarg1.find(" ")); 71 72 return curcmdarg1; 73 } 74 else { 75 cout << "そのようなコマンドは存在しない" << endl; 76 } 77} 78 79int Parser::arg2() 80{ 81 string curcmdarg2 = curcmd; 82 83 if (commandType() == C_PUSH || commandType() == C_POP || 84 commandType() == C_FUNCTION || commandType() == C_CALL) { 85 86 while (curcmdarg2[0] != ' ') { 87 curcmdarg2.erase(curcmdarg2.begin() + 0); 88 } 89 while (curcmdarg2[0] == ' ') { 90 curcmdarg2.erase(curcmdarg2.begin() + 0); 91 } 92 while (curcmdarg2[0] != ' ') { 93 curcmdarg2.erase(curcmdarg2.begin() + 0); 94 } 95 while (curcmdarg2[0] == ' ') { 96 curcmdarg2.erase(curcmdarg2.begin() + 0); 97 } 98 curcmdarg2 = curcmdarg2.substr(0, curcmdarg2.find(" ")); 99 //cout << "curcmdarg2 " << curcmdarg2 << endl; 100 return stoi(curcmdarg2); 101 } 102} 103

#CodeWriter.h

C++

1#pragma once 2#include <fstream> 3#include <sstream> 4#include <string> 5#include <iostream> 6 7class CodeWriter { 8public: 9 std::string outfilename; 10 CodeWriter(Parser parser); //出力先ファイルを開く 11 void setFileName(std::string fileName); 12 void writeArithmatic(std::string command); 13 void writePushPop(std::string command, std::string segment, int index); 14 void close(); 15 std::ofstream ofs; 16};

#CodeWriter.cpp

C++

1#include "Parser.h" 2#include "CodeWriter.h" 3 4CodeWriter::CodeWriter(Parser parser) 5{ 6 outfilename = parser.infilename; 7 outfilename.erase(outfilename.find(".") + 1, outfilename.find(".") + 3); 8 outfilename += "hack"; 9 ofs.open(outfilename); 10}

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

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

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

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

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

guest

回答1

0

ベストアンサー

こんにちは。

Parser::Parser(const Parser &)はコピー・コンストラクタです。
コピー・コンストラクタは自動生成されることも多いのですが、メンバ変数の中にコピーできない変数があると自動生成されません。
そして、std::ifstream ifs;はコピーできないので、Parserのコピー・コンストラクタも自動生成されません。

そして、CodeWriterのコンストラクタは、Parserのインスタンスを受け取っています。ポインタ渡しや参照渡しはないので、Parserはコピーして渡されます。(int型等の変数をポインタ渡しや参照渡ししなければコピーされるのと同じです。)
その時、コピー・コンストラクタが呼ばれます。
が、コピー・コンストラクタが自動生成されていない(=削除された)ため、「削除されたコピー・コンストラクタを呼び出している」エラーとなります。

CodeWriterのコンストラクタはParserをコピーして受け取る必要はなさそうですので、参照渡しにすることで回避できるだろうと思います。

CodeWriterの中でParserを変更していないので、const参照渡しするのが望ましいです。
CodeWriter::CodeWriter(Parser const& parser);

投稿2019/05/07 16:58

編集2019/05/07 16:59
Chironian

総合スコア23272

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

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

robomoco

2019/05/07 17:07

値渡しでしたね。気づきませんでした。 とても詳しく解説していただきありがとうございます。 参照渡しにしたら無事動きました<^^>
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問