İfadenin sınıf türü olmalıdır


82

Bir süredir c ++ 'da kodlamadım ve bu basit parçacığı derlemeye çalıştığımda takılı kaldım:

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

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

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

2
"Bu değil" yazan satır aslında sorun değil, bu da sorunuzun kafa karıştırıcı görünmesine neden oluyor.
juanchopanza

Yanıtlar:


166

Bu bir işaretçi, bunun yerine şunu deneyin:

a->f();

Temel olarak operatör .(bir nesnenin alanlarına ve yöntemlerine erişmek için kullanılır) nesneler ve referanslar üzerinde kullanılır, bu nedenle:

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

Bir işaretçi türünüz varsa, bir referans almak için önce referansını kaldırmanız gerekir:

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

a->bNotasyonu genellikle sadece bir kısaltmadır (*a).b.

Akıllı işaretçiler hakkında bir not

operator->Özellikle akıllı işaretçiler tarafından kullanılan, aşırı yüklenebilir. Ne zaman akıllı işaretçiler kullanıyoruz , o zaman da kullanmak ->sivri nesne başvurmak için:

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

Sadece C ++ 'yı başlatırken, bir işaretçi mi yoksa bir referans mı kullanacağınızı anlamak için yine de onu bir otomatizm haline getirmek zorundasınız. Benim özel durumumda tek ihtiyacım olan bir referanstı, ancak nedense bunun yerine bir işaretçi geçtim. Her neyse, net açıklama için teşekkürler!
Guillaume M

13

Bir analize izin verin.

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

Genel bir tavsiye olarak:

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.

Genel bir kural olarak: Belleği kendi başınıza yönetmeniz gerekiyorsa, genellikle halihazırda RAII prensibini izleyen bir üst yönetici veya alternatif mevcuttur.


9

Özet : Yerine a.f();olması gerektiğia->f();

Ana olarak tanımlanmış olan bir bir işaretçi olarak nesne A kullanarak fonksiyonları erişebilir, böylece ->operatör.

Bir alternatif , ama daha az okunaklı bir yöntemdir(*a).f()

a.f()a şu şekilde bildirilmiş olsaydı, f () öğesine erişmek için kullanılabilirdi : A a;


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.