【问题标题】:Modifying a pointer within a function (passing another pointer as a parameter)修改函数内的指针(将另一个指针作为参数传递)
【发布时间】:2018-11-01 17:43:42
【问题描述】:

我在将指针传递给由另一个指针调用的函数时遇到问题。我正在尝试修改一个调用函数 min 的指针(即 p1)(即 p1->min()),该函数将指针作为参数(即 p1->min(*p2))。注意: *p2 根本没有被修改,只是传递了它的值,p1 将根据 p2 的值进行修改。

注意:我删除了不相关的代码(仅在函数内部,其他一切按原样)以使其更易于阅读。

测试.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。

请帮忙。

【问题讨论】:

  • Test::min 的声明与其定义不符。论据不同。你确定你想让min返回void*吗?返回值有什么意义?
  • void*void 不同。投票结束为拼写错误
  • 我不需要返回值。 p1->min(*p2) 只是修改了p1,不需要返回任何东西。
  • 我看不到基类或派生类。如果你不打算改变返回类型,那么你必须返回一些东西。
  • tbh 我认为这个问题是火车失事。我建议你创建一个包含minimal reproducible example 的新文件(即包括你的基地)

标签: c++ pointers parameter-passing


【解决方案1】:

奇怪的是它被声明为无效

不,不是。

   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 和 @ 987654324@").

如果您开始将它们向左对齐(这不会影响程序的语义,它只是样式),您的意图和类型的含义就会很清楚:

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

现在您可以一目了然地看到您的返回类型不是您认为的那样,并且可以更正Test::min(可能还有Test::create)的声明。

有些人会开始讨论内部语法如何将 * 绑定到名称而不是类型,或者关于左对齐方法如何使正确处理真正重要的事情变得更加尴尬和常用的构造,多变量声明。忽略他们!

从更广泛的意义上讲,这里有很多提示,我建议尽量减少这些提示。只会带来不必要的麻烦。 爱的对象。

【讨论】:

  • 感谢您的澄清。
【解决方案2】:
void *Test::min(const Test *&p) { /* modifies vec */ }

如果此函数没有返回语句,请从 void * 中删除 *

【讨论】:

    【解决方案3】:

    我的问题的解决方案是我需要返回一个 void 指针。这可能会导致与当前问题无关的其他事情的问题,但是这种格式有特定的参数要遵循,这就是为什么我提到 main 不能改变,除其他外(包括格式)。再次感谢。

    【讨论】:

    • 只是任何void *?你最好检查一下它的用途。
    • 这听起来不对。如果您的函数确实需要在 void 指针中返回某些内容,那么您已经这样做了。所以听起来你刚刚使用了错误的返回类型,通过返回一些虚假/虚拟值来关闭编译器。这不是正确的解决方案。
    • void* Test::min(const Test &p) { // 一堆代码;返回这个; } 为我工作。我可以使用传入指针中的引用值来修改指针。它可以按照我的意愿编译和工作。
    • 就像我说的,我必须遵循某些参数。不幸的是,这意味着它可能看起来不高效或不美观。我可以让它看起来更高效,但这需要更改 main 并在基类中添加构造函数并更改许多其他内容,当指定遵循某些参数时会导致问题。总而言之,这个问题已经解决了,它做了我想要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-08
    • 2012-01-24
    • 2021-10-05
    • 2021-12-18
    • 1970-01-01
    • 2015-05-09
    • 2012-09-10
    相关资源
    最近更新 更多