Переопределение типов классов - c ++ - PullRequest
0 голосов
/ 04 ноября 2010

Я понимаю проблему, с которой сталкиваюсь с моим кодом, но попытка некоторых вещей, которые предлагают другие, не исправляет мою ошибку.

Вот мои сообщения об ошибках:

In file included from proj07.driver.cpp:4:
proj07.string.cpp:10: error: redefinition of 'String::String()'
/user/cse232/Projects/project07.string.h:25: error: 'String::String()' previously defined here
proj07.string.cpp: In constructor 'String::String(const char*)':
proj07.string.cpp:19: error: expected primary-expression before 'char'
proj07.string.cpp:19: error: expected `;' before 'char'
make: *** [proj07.driver.o] Error 1

Вот тот, о котором я беспокоюсь:

proj07.string.cpp:10: error: redefinition of 'String::String()'
/user/cse232/Projects/project07.string.h:25: error: 'String::String()' previously defined here

Я знаю, что я должен был определить свой интерфейсный файл один раз, но я не уверен, что изменить, потому что все, что я пытаюсь, приносит больше проблем.

Мой драйвер (proj07.driver.cpp):

using namespace std;

#include <iostream>
#include "proj07.string.cpp"

int main()
{
  const char string1[] = {'a', 'b', 'c', 'd', 'e', 'f'};
  String test1();
  String test2(string1);
}

Мой файл поддержки (proj07.support.cpp):

/* Implementation file for type "String" */

using namespace std;

#include <iostream>
#include "/user/cse232/Projects/project07.string.h"

/*Default constructor*/

String::String()
{
  Capacity = 0;
  Length = 0;
  Mem = NULL;
}

String::String( const char[] )
{
  cout << char.length[]; //Function not implemented yet
}

Мой make-файл:

#
# Project 07
#

proj07.exe: proj07.driver.o proj07.string.o
        g++ -o proj07.exe proj.driver. proj07.string.o

proj07.driver.o: proj07.driver.cpp ~cse232/Projects/project07.string.h
        g++ -Wall -c proj07.driver.cpp

proj07.string.o: proj07.string.cpp ~cse232/Projects/project07.string.h
        g++ -Wall -c proj07.string.cpp

clean:
        rm -f proj07.*.o proj07.exe

И заголовочный файл - в него входит множество функций класса, которые я еще не выполнял. Это неизменно.

/******************************************************************************
   Project #7 -- Interface file for type "String"
******************************************************************************/

#ifndef STRING_
#define STRING_

using namespace std;

#include <iostream>

class String
{
  private:

    unsigned Capacity;  // Number of memory locations reserved
    unsigned Length;    // Number of memory locations in use
    char * Mem;         // Pointer to memory to hold characters

  public:

    // Construct empty string
    //
    String()
    {
      Capacity = 0;
      Length = 0;
      Mem = NULL;
    }

    // Reset string to empty
    //
    void reset() { Length = 0; }

    // Return string capacity and length
    //
    unsigned capacity() const { return Capacity; }
    unsigned length() const { return Length; }

    // Return string status
    //
    bool empty() const { return Length == 0; }

    // Return reference to element I
    //
    char& operator[]( unsigned I ) { return Mem[I]; }

    // Return constant reference to element I
    //
    const char& operator[]( unsigned I ) const { return Mem[I]; }

    // Destroy string
    //
    ~String();

    // Construct string by copying existing string
    //
    String( const String& );

    // Construct string by copying C-style character string
    //
    String( const char[] );

    // Copy string into the current string
    //
    String& operator=( const String& );                                 

    // Append string to the current string
    //
    String& operator+=( const String& );
};

// Return string which is the concatenation of two strings
//
String operator+( const String&, const String& );

// Compare two strings (equality and relational operators)
//
bool operator==( const String&, const String& );
bool operator< ( const String&, const String& );

// Output string to stream
//
ostream& operator<<( ostream&, const String& );

// Input string from stream
//
istream& operator>>( istream&, String& );

#endif

Я понимаю, что проблема как-то связана с моими утверждениями #include, но я путаюсь, какие из них изменить. Если кто-то может показать мне, что я делаю неправильно, я был бы очень благодарен. Спасибо!

Ответы [ 3 ]

6 голосов
/ 04 ноября 2010
#include "proj07.string.cpp"

Вам нужно включить файл заголовка, а не файл .cpp.Если вы включите файл .cpp, который предположительно содержит определения в нем, в несколько файлов .cpp, то при сборке вы получите несколько определений ошибок (поскольку вещи определяются более одного раза в разных.файлы cpp).

4 голосов
/ 04 ноября 2010

В дополнение к тому, что сказал Джеймс МакНеллис , вы определили конструктор по умолчанию в двух разных местах:

В project07.string.h:

class String 
{ 
  private: 

    unsigned Capacity;  // Number of memory locations reserved 
    unsigned Length;    // Number of memory locations in use 
    char * Mem;         // Pointer to memory to hold characters 

  public: 

    // Construct empty string 
    // 
    String() 
    { 
      Capacity = 0; 
      Length = 0; 
      Mem = NULL; 
    }
    /* ... */ 
};

И в proj07.support.cpp:

#include "/user/cse232/Projects/project07.string.h" 

/*Default constructor*/

String::String() 
{ 
  Capacity = 0; 
  Length = 0; 
  Mem = NULL; 
} 

Поскольку вы включили string.h в support.cpp, компилятор видит две разные реализации конструктора String по умолчанию, что нарушает правило One Definition.


Некоторые комментарии, не относящиеся к вашей проблеме:

Я знаю, что вы не можете изменить project07.string.h, но на самом деле в нем не должно быть using namespace std, подобного этому.Это делает так, что для любого файла, включающего project07.string.h, будет выгружено все пространство имен std, что увеличивает вероятность того, что один из ваших идентификаторов будет конфликтовать с ним.

Кроме того, кажется, что классДля объявления требуется только предварительное объявление ostream и istream.В этом случае вам нужно всего лишь #include <iosfwd> вместо всего <iostream>.

1 голос
/ 04 ноября 2010

Ваш конструктор String, как указано в сообщении, определяется дважды.Один раз в определении класса:

class String {
    // Construct empty string
    //
    String()
    {
         Capacity = 0;
         Length = 0;
         Mem = NULL;
    }
};

и один раз в файле string.cpp, например:

String::String()
{
    Capacity = 0;
    Length = 0;
    Mem = NULL;
}

Кроме того, вы можете включить string.h в основную программу, а не main.cpp, иначе вы получите ошибки компоновщика с вашим текущим make-файлом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...