Od jakiegoś czasu nie kodowałem w C ++ i utknąłem, kiedy próbowałem skompilować ten prosty fragment:
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
adrianton3
źródło
źródło
Odpowiedzi:
To wskaźnik, więc zamiast tego spróbuj:
Zasadniczo operator
.
(używany do uzyskiwania dostępu do pól i metod obiektu) jest używany na obiektach i referencjach, więc:Jeśli masz typ wskaźnika, musisz najpierw wyłuskać go, aby uzyskać odniesienie:
A* ptr = new A(); (*ptr).f(); ptr->f();
a->b
Notacja jest zazwyczaj tylko skrótem(*a).b
.Uwaga na temat inteligentnych wskaźników
operator->
Może być przeciążona, który jest przede wszystkim używany przez inteligentne kursory. Kiedy używasz inteligentnych wskaźników , używasz również->
w odniesieniu do wskazanego obiektu:auto ptr = make_unique<A>(); ptr->f();
źródło
Pozwól na analizę.
#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. }
Jako ogólna rada:
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.
Praktyczna zasada: jeśli chcesz samodzielnie zarządzać pamięcią, na ogół jest już dostępny przełożony menedżer lub alternatywa, która działa zgodnie z zasadą RAII.
źródło
Podsumowanie : zamiast
a.f();
tego powinno byća->f();
Zasadniczo zdefiniowałeś a jako wskaźnik do obiektu A , więc możesz uzyskać dostęp do funkcji za pomocą
->
operatora.Alternatywny , ale jest mniej czytelny sposób
(*a).f()
a.f()
mógł zostać użyty do uzyskania dostępu do f (), jeśli a został zadeklarowany jako:A a;
źródło
a
jest wskaźnikiem. Trzeba użyć->
, nie.
źródło