2016-06-24 11 views
2

C++用のカスタムStringクラスを作成したいと思います。私はこれを行うときには:C++ - '(const char *)'はスコープ内で宣言されていませんか?

g++ test.cpp sys/Base.h sys/Base.cpp 

を私はこのエラーを取得する:

sys/Base.cpp: In function 'const char* Base::toChar()': 
sys/Base.cpp:57:13: error: 'strval' was not declared in this scope 
     return strval; 
      ^
sys/Base.cpp: In function 'std::string Base::toStr()': 
sys/Base.cpp:60:20: error: 'strval' was not declared in this scope 
     return string(strval); 
        ^

TEST.CPP

#include "sys/Base.h" 
int main() { 
    Base::write("Hello there.\n"); 
    return 0; 
} 

SYS/Base.h

// Header file handling 
#ifndef ARAVK_BASE_H 
#define ARAVK_BASE_H 

// Includes 
#include <string> 

// Global variables 
#define EXIT_YAY 0 
#define EXIT_ERR 1 

using namespace std; 

namespace Base { 
    // Classes: 
     class String { 
       static const char* strval; 
      public: 
       // Constructors: 
        String(); 
        String(char[]); 
        String(const char*); 
        String(string); 
       // Destructors: 
        ~String(); 

       // Operators: 
        // = 
         void operator=(const String&); 
         void operator=(const char*&); 
         void operator=(const string&); 

       // Conversion: 
        const char* toChar() const; 
        string toStr() const; 
     }; 
    // Functions: 
     // Input-Output: 
      // Write: 
       void write(String); 
       void write(string); 
       void write(const char*); 
      // Read: 
       String read(); 

     // Executing: 
      String run(String); 
} 
#endif 

SYS /ベース.cpp

// Including 
#include "Base.h" 
#include <string> 
#include <stdio.h> 
#include <stdlib.h> 
#include <cstdio> 
#include <iostream> 
#include <memory> 
#include <stdexcept> 

// Global variables 
#define EXIT_ERR 1 
#define EXIT_YAY 0 

/* ------------------------ */ 
using namespace std; 

namespace Base { 
    // Classes 
     // String functions 
      // Constructors 
       String::String() { 
        const char* strval = ""; 
       } 
       String::String(const char* str) { 
        const char* strval = str; 
       } 
       String::String(string str) { 
        const char* strval = str.c_str(); 
       } 
       String::String(char str[]) { 
        const char* strval = str; 
       } 
      // Destructors 
       String::~String() { 
        delete strval; 
       } 
      // Operators 
       // = 
        void String::operator=(const String &strp) { 
         strval = strp.toChar(); 
        } 
        void String::operator=(const char* &strp) { 
         strval = strp; 
        } 
        void String::operator=(const string &strp) { 
         strval = strp.c_str(); 
        } 
      // Conversion: 
       const char* toChar() { 
        return strval; 
       } 
       string toStr() { 
        return string(strval); 
       } 

    // Functions: 
     // Input-Output: 
      // Write 
       void write(String str)  { printf(str.toChar()); } 
       void write(const char* str) { printf(str);    } 
       void write(string str)  { printf(str.c_str()); } 
      // Read 
       String read()      { char str[100]; scanf("%s", str); return String(str); } 
       //TODO: More to come 

     // Executing 
      /*String run(String command) { 
       const char* cmd = command.toChar(); 
       char buffer[128]; 
       string result = ""; 
       std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose); 
       if (!pipe) throw runtime_error("popen() failed!"); 
       while (!feof(pipe.get())) { 
        if (fgets(buffer, 128, pipe.get()) != NULL) 
         result += buffer; 
       } 
       return String(result); 
      }*/ 
      String run(String command) { 
       char buffer[128]; 
       std::string result = ""; 
       const char* cmd = command.toChar(); 
       FILE* pipe = popen(cmd, "r"); 
       if (!pipe) throw std::runtime_error("popen() failed!"); 
       try { 
         while (!feof(pipe)) { 
           if (fgets(buffer, 128, pipe) != NULL) 
             result += buffer; 
         } 
       } catch (...) { 
         pclose(pipe); 
         throw; 
       } 
       pclose(pipe); 
       return String(result); 
      } 

} 

なぜこれが起こっているのか分かりません。私はそれがconst char * 'strval'の宣言/定義方法に関連していると思います。誰でも助けることができますか? P.S:答えは大きすぎる場合には、このプロジェクトはGitHubの上にある:AravK/C-Applications

+0

あなたの 'String'コンストラクタはすべて、すぐに破棄されるローカル変数を宣言します。あなたは何をしようとしているのですか? –

+0

あなたの 'const char * strval'は静的ではないようです – LibertyPaul

+1

あなたのコードには非常に間違ったことがたくさんあります。これはC++の初心者でも大丈夫ですが、コード内のすべての問題を指摘するのは非常に幅広い答えです。それはこのサイトにはあまり適していません。 [C++の良い本](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)をチェックすることをお勧めします。 – Zulan

答えて

3

のは、あなたのコンストラクタを見てみましょう:

  String::String() { 
       const char* strval = ""; 
      } 

これはstrval呼ばローカル変数を宣言します。変数はコンストラクタに対してローカルです。コンストラクタの実行が完了すると存在しません。

代わりに必要なのはメンバ変数です。クラス内で宣言しますが、ではなく、メンバメソッドまたはコンストラクタ内でです。実際には、あなたはすでにヘッダファイルにそのように定義されています

class String { 
      static const char* strval; 

だから、あなたのコンストラクタからconst char *を削除し、行は既存の変数への代入になるように、クラス修飾子を追加するのではなく、地元の作成:

  String::String() { 
       String::strval = ""; 
      } 

そしてまた、あなたのエラーを与えているreturn文を変更します。

   return String::strval; 

それとも - これはあなたが本当にを望ん可能性がある - 変数の定義からstatic修飾子を削除し、ちょうどに代わりにコンストラクタを変更します、必ずしも動的に割り当てられていなかった

  String::String() { 
       strval = ""; 
      } 

さらに、あなたのデストラクタ誤っdelete sのデータ

  String::~String() { 
       delete strval; 
      } 

これは再加工が必要です。現在のところ、最も簡単な解決策は、delete strvalを完全に削除することです。

あなたread()機能が潜在的に固定サイズのバッファと、未知の入力サイズでのscanf( "%s" を)使用することにより、バッファオーバーフローを扇動:

最後に
char str[100]; scanf("%s", str); return String(str); 

、あなたのコマンドラインは:

g++ test.cpp sys/Base.h sys/Base.cpp 

... ではないには、ヘッダーファイル(Base.h)が含まれています。あなたはコンパイルしたい単位を指定しており、Base.hはすでにBase.cppに入っています。間違いなくコンパイルする必要があるスタンドアロンユニットではありません。

+0

この回答は網羅的ではありません。コード内のメモリ管理に関するすべてが間違っています。私はこの質問に網羅的な答えを期待していませんが、コンパイルを修正した不完全なものを提供するのは間違いです。 – Zulan

+0

@ Zulan特定の問題を指摘できる場合は、幸いにそれらを解答に編集します。 (デストラクタについてのメモを入れておいてください。) – davmac

+0

たとえば 'char str [100]; scanf( "%s"、str);バッファオーバーフローとスタックメモリの所有権の移転を組み合わせたreturn String(str);メモリに関するすべてのことが間違っています。これらの問題はここで答えが出るには広すぎますが、OPは彼が基礎についてもっと学ぶべきであることを知る必要があります。 – Zulan

0

はいクラス内の変数をフィールドとして定義しませんでした。 あなたのコンストラクタには3つの地域デーレーションがあります。 ヘッダーに追加したとおりに追加してください。

static const char* strval 

コンストラクタ内のdfinitionを削除してください。割り当ての部分はそのままにしておいてください。 について

関連する問題