2013-04-14 4 views
0

Не могли бы вы помочь мне понять, почему в этих двух строках я получаю ошибки: 1) C2143: синтаксическая ошибка: отсутствует ';' перед '*' 2) ошибка C4430: отсутствует спецификатор типа - int. Примечание: C++ не поддерживает default-int.Почему мой класс недоступен, тогда как я включил заголовочный файл

MyString* m_pStr; // Link to a dynamically created string. 
MyString* pPrev; // Pointer to the next counter. 

MyString.h

#pragma once 
#include <iostream> 
#include "counter.h" 

using namespace std; 
class MyString 
{ 
    char* m_pStr; //String which is a member of the class. 
    void CreateArray(const char * pStr); 
    Counter* m_pMyCounter; // Pointer to its own counter. 

    public: 
     MyString(const char* pStr = ""); 
     MyString(const MyString & other); 
     MyString(MyString && other); 
     ~MyString(); 

     const char * GetString(); 
     void SetNewString(char * str); 

     void printAllStrings(); 
     void ChangeCase(); 
     void printAlphabetically(); 
}; 

MyString.cpp

#include "myString.h" 
#include <iostream> 
using namespace std; 


MyString::MyString(const char* pStr){ 
    this->CreateArray(pStr); 
    strcpy(m_pStr, pStr); 
}; 
void MyString:: CreateArray(const char * pStr){ 
    int size_of_string = strlen(pStr)+1;  
    m_pStr = new char[size_of_string]; 
} 

MyString::MyString(const MyString & other){ 
    this->CreateArray(other.m_pStr); 
    strcpy(m_pStr, other.m_pStr); 
} 

MyString::MyString(MyString && other){ 
    this->m_pStr = other.m_pStr; 
    other.m_pStr = nullptr; 
} 

MyString::~MyString(){ 
    delete[] m_pStr; 
} 

const char * MyString:: GetString(){ 
    return m_pStr; 
} 

void MyString:: SetNewString(char * str){ 
    this->CreateArray(str); 
    strcpy(m_pStr, str); 
} 

counter.h

#pragma once 
#include "myString.h" 
#include <iostream> 
using namespace std; 

class Counter{ 
    private: 
     MyString* m_pStr; // Link to a dynamically created string. 
     int m_nOwners; // Counter of users of this string. 
     MyString* pPrev; // Pointer to the next counter. 
    public: 
     Counter(); 
     //Copy constructor. 
     ~Counter(); 
     void AddUser(); 
     void RemoveUser(); 
}; 
+0

Ни один из ваших файлов заголовков не должен включать другое как есть. – chris

+0

И вы можете подумать о том, чтобы иметь один заголовок (определяющий как 'Counter', так и' MyString') –

+0

Вскипятите свой код до одного «файла», который демонстрирует проблемы. Там много пуха. –

ответ

1

Для дальнейшего использования для других, эти причины я обычно найти эту ошибку:

  • Циклическая включают (да, это вам на этот раз). Заголовок A зависит от B зависит от A. Это означает, что когда вы включаете A сначала, B находится над ним. B пытается включить A над ним (снова), но это предотвращает «прагма один раз» или защита включения. Результат состоит в том, что B не имеет определения A над ним, но не будет работать без => этой ошибки.
  • Включение охранник messup. Вы создаете новые файлы заголовков, и у многих людей есть привычка копировать/вставлять существующий файл заголовка.В этом новом заголовочном файле могут быть отключены защитные устройства включения. Если это произойдет, есть include, но защита включения включит только новый или старый заголовочный файл, в зависимости от того, что наступит раньше. Конечным результатом является то, что в некоторых файлах, содержащих новый заголовок, он не будет работать, и класс будет неопределенным. Может задерживаться в течение долгого времени, я видел базы кода, у которых это условие существовало годами незаметно. Не подходит для пользователей «прагма один раз».
  • На самом деле забыл написать класс/опечатки, используемые или определение/капитализация, отличающиеся друг от друга. Очевидная проблема, очевидное решение.
2

У вас есть цикл во входящих файлах. Компилятор не выполняет бесконечную рекурсию, потому что вы добавили опцию #pragma once.

Вот что делает компилятор:

  1. Прочитайте файл CPP. Найдите #include "myString.h".
  2. Прочтите файл "myString.h", найдите #include "counter.h".
  3. Прочтите файл "counter.h", найдите #include "myString.h", но игнорируйте его из-за #pragma once.
  4. Продолжить с "counter.h", прочитать строку MyString* m_pStr;, не знаю, что такое MyString, с ошибкой с сообщением менее полезного.

Теперь решение должно заключаться в добавлении объявления друг к другу в файлы заголовков. То есть, добавьте следующую строку в начало myString.h, сразу после includes.

class Counter; 

И следующая строка начала counter.h:

class MyString; 

Теперь, с этой декларацией в рамках, но без определения класса, есть некоторые вещи, которые вы можете сделать, и некоторые вещи, которые вы не можете do: в основном вы можете объявлять указатели и ссылки. Любое другое использование класса должно перейти в файл CPP.

И вы даже можете избавиться от обоих рекурсивных includes!

Смежные вопросы