【问题标题】:Expression must have class type表达式必须具有类类型
【发布时间】:2011-09-26 17:12:58
【问题描述】:

我已经有一段时间没有用 c++ 编码了,当我试图编译这个简单的 sn-p 时,我被卡住了:

class A
{
  public:
    void f() {}
};

int main()
{
  {
    A a;
    a.f(); // works fine
  }

  {
    A *a = new A();
    a.f(); // this doesn't
  }
}

【问题讨论】:

  • 说“这不是”的那一行实际上是可以的,这让你的问题看起来很混乱。

标签: c++ class new-operator


【解决方案1】:

这是一个指针,所以试试:

a->f();

基本上运算符.(用于访问对象的字段和方法)用于对象和引用,所以:

A a;
a.f();
A& ref = a;
ref.f();

如果你有一个指针类型,你必须先解引用它才能获得引用:

A* ptr = new A();
(*ptr).f();
ptr->f();

a->b 符号通常只是 (*a).b 的简写。

关于智能指针的说明

operator-> 可以重载,尤其是智能指针使用。当you're using smart pointers,那么你也用->来指代指向的对象:

auto ptr = make_unique<A>();
ptr->f();

【讨论】:

  • 刚开始使用 C++,仍然需要自动判断是使用指针还是引用。在我的特殊情况下,我只需要一个引用,但由于某种原因,我改为传递了一个指针。无论如何,感谢您的明确解释!
【解决方案2】:

总结:应该是a-&gt;f();而不是a-&gt;f();

在 main 中,您已将 a 定义为指向 A 的对象的指针,因此您可以使用 -&gt; 运算符访问函数。

一个替代,但可读性较差的方式是(*a).f()

a.f() 可以用于访问 f(),如果 a 被声明为: A a;

【讨论】:

    【解决方案3】:

    a 是一个指针。你需要使用-&gt;,而不是.

    【讨论】:

      【解决方案4】:

      允许分析。

      #include <iostream>   // not #include "iostream"
      using namespace std;  // in this case okay, but never do that in header files
      
      class A
      {
       public:
        void f() { cout<<"f()\n"; }
      };
      
      int main()
      {
       /*
       // A a; //this works
       A *a = new A(); //this doesn't
       a.f(); // "f has not been declared"
       */ // below
      
      
       // system("pause");  <-- Don't do this. It is non-portable code. I guess your 
       //                       teacher told you this?
       //                       Better: In your IDE there is prolly an option somewhere
       //                               to not close the terminal/console-window.
       //                       If you compile on a CLI, it is not needed at all.
      }
      

      一般建议:

      0) Prefer automatic variables
        int a;
        MyClass myInstance;
        std::vector<int> myIntVector;
      
      1) If you need data sharing on big objects down 
         the call hierarchy, prefer references:
      
        void foo (std::vector<int> const &input) {...}
        void bar () { 
             std::vector<int> something;
             ...
             foo (something);
        }
      
      
      2) If you need data sharing up the call hierarchy, prefer smart-pointers
         that automatically manage deletion and reference counting.
      
      3) If you need an array, use std::vector<> instead in most cases.
         std::vector<> is ought to be the one default container.
      
      4) I've yet to find a good reason for blank pointers.
      
         -> Hard to get right exception safe
      
             class Foo {
                 Foo () : a(new int[512]), b(new int[512]) {}
                 ~Foo() {
                     delete [] b;
                     delete [] a;
                 }
             };
      
             -> if the second new[] fails, Foo leaks memory, because the
                destructor is never called. Avoid this easily by using 
                one of the standard containers, like std::vector, or
                smart-pointers.
      

      根据经验:如果您需要自己管理内存,通常已经有一个上级经理或替代方案可用,遵循 RAII 原则。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-16
        • 2022-01-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多