Недопустимый вызов нестатической функции-члена

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

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

Однако при компиляции я столкнулся с ошибкой: ошибка C2352: 'main::StringToList': недопустимый вызов нестатического члена. Линия: 7;

Я предоставляю вам свои файлы main.cpp и main.h.

Спасибо за любой

main.cpp

#include "main.h"

int main()
{
main::node *head = main::StringToList("123");

main::node *temp = new main::node;

temp = head;
while (temp->next != NULL)
{
    cout << temp->data;
    temp = temp->next;
}

std::cout << "\nThe program has completed successfully\n\n";
system("PAUSE");
return 0;
}

main::node * StringToList(string number) 
{

int loopTimes = number.length() - 1; 
int looper = 0;         
int *i = new int;       
i = &looper;            
main::node *temp = new main::node;  
main::node *head;               
head = temp;            
for ( i = &loopTimes ; *i >= 0; *i = *i - 1) 
{
    temp->data = number[*i] - 48;   
    main::node *temp2 = new main::node;         
    temp->next = temp2;             
    temp = temp2;                   
}
temp->next = NULL;                  
return head;
}

main.h

#ifndef MAIN_H
#define MAIN_H

#include <iostream>
#include <string>

using namespace std;

class main
{
public:
typedef struct node
{
    int data;
    node *next;
};
node* StringToList (string number);
};

#endif

person Avgar    schedule 23.08.2012    source источник
comment
Именование вашего класса main действительно сбивает с толку.   -  person Bartek Banachewicz    schedule 23.08.2012
comment
int *i = new int; i = &looper; Почему вы создаете новое целое число, а затем сразу же отбрасываете указатель на него, чтобы он был потерян навсегда?   -  person David Schwartz    schedule 23.08.2012


Ответы (3)


Вам нужно создать экземпляр основного класса и вызвать StringToList в качестве члена:

main* m = new main;
main::node *head = m->StringToList("123");
...
delete m;
person Andreas Fester    schedule 23.08.2012
comment
Даже если имеет смысл, чтобы функция была нестатической (что, вероятно, не так), нет причин создавать объект с new и определенно нет причин для его утечки. - person Mike Seymour; 23.08.2012
comment
Я определенно согласен с этим - с исходным кодом, показанным выше, гораздо больше проблем, будь то имена переменных, отступы или что-то еще, но основной причиной ошибки компилятора был вызов метода как статический, поэтому вам нужно либо определить это как статическое или вызовите его как член :-) (и, конечно, очистите потом) - person Andreas Fester; 23.08.2012
comment
В этом случае создайте временный или автоматический объект. Здесь нет абсолютно никакой причины для динамического распределения, даже если вы не забудете очистить. (Хотя временное было бы проблематично, так как main() будет интерпретироваться как вызов функции). - person Mike Seymour; 23.08.2012

Вам нужно будет объявить StringToList как static, чтобы это работало:

static node* StringToList(string number);

В этой строке:

main::node *head = main::StringToList("123");

Вы пытаетесь вызвать StringToList без предварительного создания объекта типа main. Поскольку это нестатическая функция-член, это не работает. Вы должны были бы сделать это так:

main foo;
main::node *head foo.StringToList("123");

Что на самом деле не имеет смысла для вашего варианта использования.

person Björn Pollex    schedule 23.08.2012
comment
Это будет работать, но разве ОП не должен вместо этого создавать конструктор? - person Bartek Banachewicz; 23.08.2012
comment
Что ж, код OP немного проблематичен. Для классического связанного списка имеет смысл иметь node-класс и отдельную функцию для построения списка. Если бы вы сделали это в конструкторе класса node, вы бы получили рекурсивный вызов конструктора, что может сбивать с толку. - person Björn Pollex; 23.08.2012
comment
@Anonymous: Конечно, можно. Если бы были какие-то нестатические элементы, то он не мог бы получить к ним доступ, но их нет. (Конечно, это делает существование самого класса довольно бессмысленным, но критиковать дизайн несколько не по теме). - person Mike Seymour; 23.08.2012
comment
@Anonymous: node является общедоступным вложенным типом, и поэтому к нему можно получить доступ из любой функции, не являющейся членом. - person Björn Pollex; 23.08.2012

Поскольку node* StringToList (string number); не является статическим, вы не можете называть его main::StringToList("123");

Сначала создайте объект main, затем назовите его как

main mn;
mn.StringToList("123");

В противном случае объявите node* StringToList (string number); как static node* StringToList (string number);

person perilbrain    schedule 23.08.2012
comment
Имеет смысл сделать StringToList статической функцией-членом, а не создавать экземпляр класса. - person David Schwartz; 23.08.2012
comment
И еще более разумно избавиться от класса и поместить функцию в пространство имен, если только нет каких-то нестатических данных, виртуальных функций или чего-то еще, что не было опущено в вопросе. - person Mike Seymour; 23.08.2012
comment
@DavidSchwartz: - Думал написать то же самое, но эффект промышленного C # просто сбил меня с толку. Так что подумал лучше, Поллекс может подтвердить. - person perilbrain; 23.08.2012