Biểu thức phải có loại lớp


82

Tôi đã không viết mã bằng c ++ trong một thời gian và tôi đã gặp khó khăn khi cố gắng biên dịch đoạn mã đơn giản này:

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

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

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

2
dòng nói "điều này không" thực sự là OK, làm cho câu hỏi của bạn trông khó hiểu.
juanchopanza

Câu trả lời:


165

Đó là một con trỏ, vì vậy thay vào đó hãy thử:

a->f();

Về cơ bản, toán tử .(được sử dụng để truy cập các trường và phương thức của một đối tượng) được sử dụng trên các đối tượng và tham chiếu, vì vậy:

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

Nếu bạn có một loại con trỏ, trước tiên bạn phải tham khảo nó để có được tham chiếu:

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

Các a->bký hiệu thường chỉ là một viết tắt cho(*a).b .

Một lưu ý về con trỏ thông minh

operator->thể bị quá tải, điều này đáng chú ý được sử dụng bởi các con trỏ thông minh. Khi bạn đang sử dụng con trỏ thông minh , thì bạn cũng sử dụng ->để tham chiếu đến đối tượng được trỏ:

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

Chỉ mới bắt đầu C ++, vẫn phải làm cho nó trở thành một chủ nghĩa tự động để tìm ra xem nên sử dụng một con trỏ hay một tham chiếu. Trong trường hợp cụ thể của tôi, tất cả những gì tôi cần là một tham chiếu, nhưng vì lý do nào đó tôi đã chuyển một con trỏ. Dù sao, cảm ơn vì lời giải thích rõ ràng!
Guillaume M

13

Cho phép một phân tích.

#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.
}

Như một lời khuyên chung:

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.

Theo nguyên tắc chung: Nếu bạn cần tự quản lý bộ nhớ, nói chung đã có sẵn một trình quản lý cấp trên hoặc thay thế, một trình quản lý tuân theo nguyên tắc RAII.


9

Tóm tắt : Thay vì a.f();nó nên đượca->f();

Trong main, bạn đã định nghĩa a như một con trỏ tới đối tượng của A , vì vậy bạn có thể truy cập các hàm bằng ->toán tử.

Một cách thay thế , nhưng ít dễ đọc hơn là(*a).f()

a.f()có thể đã được sử dụng để truy cập f (), nếu a được khai báo là: A a;


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.