C ++ CLI Class проблема - PullRequest
       18

C ++ CLI Class проблема

1 голос
/ 05 июля 2010

----- привет, world 2.cpp -----

// Hello, World 2.cpp : main project file.

#include "stdafx.h"
#include "hello.h"
#include <string>

using namespace System;
using namespace std;

int main(array<System::String ^> ^args)
{
    hello hi = new hello("Bob", "Blacksmith");
    Console::WriteLine(L"Hello, " + hi.getName + "!");
    return 0;
}

----- hello.h -----

#include <string>
using namespace std;

#ifndef HELLO_H
#define HELLO_H

class hello
{
private:
    string _fname;
    string _lname;
    //hello() { } // private default constructor

public:
    hello(string fname, string lname);
    void SetName(string fname, string lname);
    string GetName();

};

#endif

----- hello.cpp -----

#include "stdafx.h"
#include "hello.h"
#include <string>
using namespace std;

hello::hello(string fname, string lname)
{
    SetName(fname, lname);
}

void hello::SetName(string fname, string lname)
{
    _fname = fname;
    _lname = lname;
}

string hello::getName()
{
    return _fname + _lname;
}

----- Ошибки -----

  • ------ Началась сборка: Проект: Hello, World 2, Конфигурация: Отладка Win32 ------
  • Hello, World 2.cpp
  • Hello, World 2.cpp (12): ошибка C2440: «инициализация»: невозможно преобразовать из «hello *» в «hello»
  • Ни один конструктор не может принять тип источника, или разрешение перегрузки конструктора было неоднозначным
  • Hello, World 2.cpp (13): ошибка C2039: 'getName': не является членом 'hello'
  • \ documents \ visual studio 2010 \ projects \ cpp \ hello, world 2 \ hello, world 2 \ hello.h (8): см. Объявление 'hello'
  • hello.cpp
  • hello.cpp (17): ошибка C2039: «getName»: не является членом «hello»
  • \ documents \ visual studio 2010 \ projects \ cpp \ hello, мир 2 \ hello, мир 2 \ hello.h (8): см. Объявление 'hello'
  • hello.cpp (19): ошибка C2065: '_fname': необъявленный идентификатор
  • hello.cpp (19): ошибка C2065: '_lname': необъявленный идентификатор
  • Генерация кода ... ========== Построение: 0 выполнено, 1 не выполнено, 0 обновлено, 0 пропущено ==========

Ответы [ 6 ]

5 голосов
/ 05 июля 2010

Сообщения об ошибках сообщают вам точно, где и в чем заключаются проблемы, хотя поначалу они могут быть немного пугающими. Может быть, я могу помочь немного демистифицировать их:

Hello, World 2.cpp (12): ошибка C2440: «инициализация»: невозможно преобразовать из «hello *» в «hello»

Это означает, что в строке 12 в Hello, World 2.cpp вы пытаетесь поместить указатель на hello (возврат из new) внутри hi, который не является типом указателя. Поскольку вам не нужен динамически размещаемый объект, просто отбросьте new.

В ситуациях, когда вам нужен динамически размещаемый объект, вы должны изменить переменную hi на hello * и добавить соответствующий delete.

Hello, World 2.cpp (13): ошибка C2039: 'getName': не является членом 'hello'

C ++ чувствителен к регистру. В одном файле у вас есть GetName, в другом у вас есть getName. Выберите один.

hello.cpp (19): ошибка C2065: '_fname': необъявленный идентификатор hello.cpp (19): ошибка C2065: '_lname': необъявленный идентификатор

Строка 19 из hello.cpp - это определение строчной буквы getName. Поскольку getName не было объявлено в классе (см. Предыдущую ошибку), компилятор не знает, что такое _fname или _lname. Эти ошибки исчезнут, когда исходные проблемы будут решены.

Редактировать

См. Ответ Сергея, чтобы узнать некоторые более общие замечания о том, что нужно исправить.

3 голосов
/ 05 июля 2010

Ключевое слово new создает указатель - если вы делаете это таким образом, 'hi' должен быть объявлен как hello*, или вы должны переписать объявление как:

hello hi(...);

Вторая ошибка вызвана чувствительностью к регистру (getName, GetName).

1 голос
/ 05 июля 2010

Есть несколько ошибок.

  • Имена файлов с пробелами.Не критично, но может привести к проблемам
  • Console::WriteLine(L"Hello, " + hi.getName + "!");

это должно быть примерно так:

 string s("Hello, ");
 s += hi->getName();
 s += "!"
 Console::WriteLine(s);
  • удалить объектывыделено с новым: delete hi;

  • string hello::getName() должно быть string hello::GetName()

  • Никогда не используйте use namespace ... в заголовочных файлах

  • Включить другие файлы в защитный блок

1 голос
/ 05 июля 2010
hello hi = new hello("William", "Dyson");  

Должно быть

hello* hi = new hello(...);   

Или

 hello hi("William", "Dyson");  ;

Console::WriteLine(L"Hello, " + hi.getName + "!");

Должно быть

Console::WriteLine(L"Hello, " + hi.getName() + "!");

Могут быть и другие ошибки, но мне нужно идти

0 голосов
/ 05 июля 2010

Если вы выделяете что-то с помощью new, вам нужно позвонить delete, когда вам это больше не нужно.

Если вы хотите использовать сборщик мусора для очистки, вы должны объявить класс как ref class hello, а затем создать его с помощью:

hello^ hi = gcnew hello(...);   
0 голосов
/ 05 июля 2010

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

  1. Поставьте вас публичными участниками на первое место
  2. пространство имен System подразумевает Managed C ++, если выне знаете, что это такое, и думаете, что вы используете простой C ++, пожалуйста, прочитайте о printf и std::cout.
  3. Строка

    hello hi = new hello("William", "Dyson");

    следует читать

    hello hi("William", "Dyson"); или hello* hi = new hello("William", "Dyson");

    Первый создает объект в стеке (который будет автоматически уничтожен при выходе из области видимости. Второй создает указатель наобъект в куче, который вам нужно будет delete до того, как указатель выйдет из области видимости (после того, как вы покончили с ним)

  4. о hello::getName(): у вас есть опечатки сЧто касается заглавных букв (getname vs getName), и это должно быть объявлено так (в заголовке и, соответственно, в исходном файле):

    const string getName() const;

    Первый const не является обязательным, но мне нравитсятаким образом, последний позволяет вам вызывать эту функцию из const hello объекта,d сообщает читателю, что функция не изменяет объект.

  5. Вы должны передать string по ссылке (здесь используется конструктор корректора):

    hello( const string &fname, const string& lname);

  6. В источниках и заголовках должны быть имена без пробелов (или специальные символы), это будет проблематично для UNIX <-> Windows, если вы не будете осторожны.

Это все, что я сейчас вижу.

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