Изменение указателя внутри функции (передача другого указателя в качестве параметра) - PullRequest
0 голосов
/ 01 ноября 2018

У меня проблемы с передачей указателя на функцию, которая вызывается другим указателем. Я пытаюсь изменить указатель (то есть p1), который вызывает функцию min (т.е. p1-> min ()), которая принимает указатель в качестве параметра (то есть p1-> min (* p2)). Примечание: * p2 вообще не изменяется, просто передается для его значений, для которых p1 будет изменяться на основе значений p2.

Примечание: я удалил нерелевантный код (только внутри функций, все остальное как есть), чтобы его было легче читать.

test.h

// Don't worry about the create method, just assume it works
// I'm having issues with the "min" function, more details below

class Test {
    protected:
        std::vector<std::vector<std::string> > vec;
    public:
        static Test *create(std::string file); // instantiates vec
        void *min(Test *); // modifies vec 
};

Test.cc

// Don't worry about create (factory method), just assume it works
// "min" is causing compiler errors (see below)

Test *Test::create(string file) { /* instantiates vec with file contents */ }
void *Test::min(const Test *&p) { /* modifies vec */ }

main.cc

// Main cannot change, this is how it must be implemented
// However, Test.cc and Test.h CAN be modified.

Test *p1 = Test::create("file1");
Test *p2 = Test::create("file2");
p1->min(*p2); // modify p1 based on values of p2, p2 is NOT modified

Ошибки компилятора:

fatal error: control reaches end of non-void function

Что странно, так это то, что он объявил void, но ожидает возвращаемого значения Итак, когда я что-то возвращаю, появляется другая ошибка компилятора

fatal error: no viable conversion from return value of type 'Test' to function return type 'void *'

Я так запутался в ошибках компиляции. Я думаю, это как-то связано с моими заявлениями. Примечание: конструктора не существует, поскольку базовый класс должен использовать метод фабрики, а производные классы используют свои собственные конструкторы, следовательно, * Test :: create и * Test :: min.

Пожалуйста, помогите.

Ответы [ 3 ]

0 голосов
/ 01 ноября 2018

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

0 голосов
/ 01 ноября 2018

Что странно в том, что объявлена ​​недействительной

Нет, это не так.

   Test *Test::create(string file) { /* instantiates vec with file contents */ }
// ^^^^^^ return type is Test*

   void *Test::min(const Test *&p) { /* modifies vec */ }
// ^^^^^^ return type is void*

К сожалению, вы используете звездочки и амперсанды, выровненные по правому краю, потому что это напрямую привело к вашей путанице. Похоже, вы забыли, что * был там, или думали, что это было частью синтаксиса самого объявления функции (например, как в вашем вопросе вы называли функции "*Test::create и *Test::min ").

Если вы начнете выравнивать их по левому краю (что не повлияет на семантику программы, это просто стиль), ваше намерение и значение типов будут понятны:

Test* Test::create(string file) { /* instantiates vec with file contents */ }
void* Test::min(const Test*& p) { /* modifies vec */ }

Теперь вы можете легко увидеть, что ваш возвращаемый тип не тот, о котором вы думали, и может исправить объявление Test::min (и, возможно, Test::create).

Некоторые люди начнут рассуждать о том, как внутренняя грамматика связывает * с именем, а не с типом, или о том, как подход с выравниванием по левому краю делает его немного более неловким, чтобы понять, что действительно важно и часто используемая конструкция, объявление нескольких переменных. Игнорировать их!

Если говорить более широко, у вас здесь много указателей, и я предлагаю попытаться минимизировать это. Это только приведет к ненужным неприятностям. Объекты любви.

0 голосов
/ 01 ноября 2018
void *Test::min(const Test *&p) { /* modifies vec */ }

Если эта функция не имеет оператора возврата, удалите * из void *.

...