2017-02-15 9 views
2

В 2-х образцах коды ниже (первый кодоблок ниже работ и 2-го нижнего блока коды не)Почему мне нужно указать переменную структуру

#include <iostream> 
#include <vector> 
#include <string> 

struct padStruct 
{ 
    int buttonID; 
    long timeMS; 
    std::string codetoSEND; 
}; 

int main() 
{ 
    padStruct s = {0,0,""}, *s2; 
    s2 = &s; 
    s.buttonID = 3; //or (*s2).buttonID = 3; 
    s.timeMS = 1200; //or (*s2).timeMS = 1200; 
    s.codetoSEND = "play song"; //or (*s2).codetoSEND = "play song"; 
    std::cout << (*s2).buttonID << ',' << (*s2).timeMS << ',' << '"' << (*s2).codetoSEND << '"' << '\n'; 
} 

Это работает.

В противоположность:

#include <iostream> 
#include <vector> 
#include <string> 

struct padStruct 
{ 
    int buttonID; 
    long timeMS; 
    std::string codetoSEND; 
}; 

int main() 
{ 
    padStruct *s = {0}; 
    //padStruct *s = {0,0,""} //Error C2078 too many initializers 
    (*s).buttonID = 3; //or (*s2).buttonID = 3; 
    (*s).timeMS = 1200; //or (*s2).timeMS = 1200; 
    (*s).codetoSEND = "play song"; //or (*s2).codetoSEND = "play song"; 
    std::cout << (*s).buttonID << ',' << (*s).timeMS << ',' << '"' << (*s).codetoSEND << '"' << '\n'; 
} 

Это не делает.

Может кто-то просто объяснить

  1. Почему я не могу инициализировать padStruct * S = {0,0, «») на нижней коде в то время как он работает на вершине в противном случае я получаю Ошибки C2078 слишком много инициализаторов |

  2. Что еще более важно, почему мне нужно создать переменную padStruct s, а затем padStruct * s2 и затем указать s2 на s? В противном случае я получаю ошибку Ошибка C2228: слева от '.buttonID' должен быть класс/структура/объединение.

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

+2

Короткий ответ «потому что C++ не работает таким образом». Перечитайте главу на своем C++, которая обсуждает, что такое указатели и как они работают. –

+1

Ум .. Потому что в верхней версии у вас есть объект класса, тогда как в нижнем коде у вас есть * указатель * на объект класса. Это две совершенно разные вещи с совершенно другой семантикой. – AnT

ответ

2

Почему я не могу инициализировать padStruct *s = {0, 0, "")

Поскольку s является указателем, а не составной тип. Он может быть инициализирован нулем, как вы это делали, или указателем на новый экземпляр padStruct, но это отдельный элемент.

почему я должен создать переменную padStructs, а затем padStruct *s2 и должны затем указать s2 на s?

Вам необходимо инициализировать указатель s2, чтобы указать экземпляр padStruct. Указывать его на s - это один из вариантов, но есть и другие варианты. Например, вы можете написать

padStruct *s = new padStruct { 0, 0, "" }; 

или даже

padStruct *s = new padStruct { 3, 1200, "play song" }; 

, чтобы избежать установки полей по одному.

Обратите внимание, что вместо (*s).buttonID можно использовать синтаксис s->buttonID.

+0

Это было просто. Большое спасибо за это ясное объяснение. –

0

На первом этапе вы определяете фактический padStruct s объект и определить другой просто указательs2 к padStruct.

padStruct s = {0,0,""}, *s2 

Для s2 = &s, что делает s2 на указатель на s нет ничего плохого, то s2 указатель адрес s, который выделяется в стеке. Поэтому, когда вы пересматриваете s2 на (*s2).buttonID, значение действительно исходит от s. (То же, что и s.buttonID)

В следующем блоке, что вы делаете, initialize a pointer with {0}. Это не верно. Указатель должен быть инициализирован как 0 или nullptr. И {0} работает только для POD struct.

padStruct *s = {0}; 

Вам нужно подготовить место для s как padStruct *s = new padStruct, то s будет на самом деле указатель на что-то реальное. И не забудьте удалить его в конце.

+0

Спасибо, basblinkenlight объяснил это немного, и вы дали немного больше в глубину. Я ценю это. :) –

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

  • Нет связанных вопросов^_^