【问题标题】:Is this' type variableofType()' function or object?这是'type variableofType()'函数还是对象?
【发布时间】:2010-09-30 00:35:13
【问题描述】:
#include<iostream>
class name
{
public:
    int a;
    name():a(0){};
};
void add(name * pname)
{
    pname = NULL;
}
int main()
{
    name varName();
    name * pName = new name();
    add(pName);
    add(&varName);//error C2664: 'add' : cannot convert parameter 1 from 'name __cdecl *)(void)' to 'name *'
}

【问题讨论】:

    标签: c++ function pointers


    【解决方案1】:

    错误在main函数的第一行:

    name varName();
    

    不是使用默认构造函数创建类 name 的实例,您实际上是在声明一个名为 varName 的新函数,没有参数,它返回一个 name 实例。

    你应该写:

    name varName;
    

    【讨论】:

    • 我遇到了这个一千次! ;-) 我认为 C++ 语言是一个成功的“模因”(查看维基百科):它是成功的,因为它让开发人员在最终掌握另一个问题时感到很聪明。这让他们受宠若惊,这就是他们喜欢它的原因。 ;-)
    • 我非常喜欢这种问题 :) 它会引起“啊哈!”对读者的影响,它为正确答案提供了很多分:)确实+1
    • 在c++中有没有类似这种语法的东西...大家应该知道abt
    • rajKumar,另一个例子见下文
    • 我的脑子里一片混乱。多年来我从未遇到过 C++,但它绝对是 +1。
    【解决方案2】:

    我认为值得告诉你一个类似的问题,这也会引起麻烦:

    struct foo { };
    struct bar { bar(foo f); };
    
    int main() {
      // does *not* create a bar object initialized by a default constructed 
      // foo object.
      bar b(foo());
    }
    

    真正的 b 是一个函数,它返回一个 bar,并将一个指向函数的指针作为第一个参数,该函数返回一个不带参数的 foo。同理:

    bar b(foo(*)());
    

    如果你想创建一个由默认构造的 foo 初始化的 bar 对象,请在参数周围加上括号。这使它看起来不再像函数声明,编译器会按照你的意愿解释它:

    bar b((foo()));
    

    还有一些不明显的情况应该引发编译器错误。 GCC 弄错了,但 Comeau 又弄对了。考虑以下 sn-p

    struct foo {
      static bool const value = false;
    };
    
    int main() {
      int v(int(foo::value));
    }
    

    您可能会期望这将获取静态常量并将其强制转换为int,将v 变量初始化为0?不,它不会按照标准,因为初始化器可以解释为声明,根据纯语法分析,如下所示

    struct foo {
      static int value;
    };
    
    // valid, parentheses are redundant! Defines `foo::value`.
    int (foo::value); 
    

    只要初始化器可以被解释为声明,在这种情况下,整个声明将声明一个函数。所以,main 中的那行声明了一个类似下面的函数,省略了多余和无意义的括号

    int v(int foo::value);
    

    这会在解析函数声明时导致编译器错误,因为函数参数名可能没有被限定。

    【讨论】:

    • 很好地回答了我的下一个问题......甚至在提问之前
    • @litb 什么决定了函数参数是按值传递还是按引用传递,它只是函数签名还是函数是如何被调用的
    • rajKumar,我过去回答了这个问题,试图为它建立一个定义:stackoverflow.com/questions/410593/…。还是你的意思是别的?
    • 那个邪恶的!我不知道 foo() 会是 foo(*)() 的别名……谢谢!
    • 是的。只是在参数列表中是相同的。否则 foo() 确实是函数的类型而不是函数指针的类型(很像 char[3] 是数组的类型,而 char(*)[4] 是数组指针)
    【解决方案3】:

    还值得注意的是,您的 add() 函数没有任何持久效果——它所做的只是为 pname 分配一个值,它是您传递给它的指针的副本。如果您想真正拥有该分配棒,则需要通过引用将指针作为“name*& pname”传递。

    【讨论】:

      【解决方案4】:
      name varName();
      

      被解释为局部函数声明。要调用默认构造函数,请使用

      name varName;
      

      相反。最令人烦恼的是,是的。

      【讨论】:

        猜你喜欢
        • 2013-06-22
        • 2011-11-18
        • 2012-09-15
        • 2023-04-01
        • 1970-01-01
        • 2014-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多