2016-10-13 2 views
2

Also komme ich aus Java, lernen C++. Ich möchte ein Programm implementieren, die wie folgt aufgerufen werden kann, durch eine Test-Datei zur Verfügung gestellt (Stiefel):Konstruieren von Objekten in C++

auto subject = anagram::anagram("diaper"); 
auto matches = subject.matches({"hello", "world", "zombies","pants"}); 
vector<string> expected; 
BOOST_REQUIRE_EQUAL_COLLECTIONS(expected.begin(), expected.end(), matches.begin(), matches.end()); 

Sehe ich es richtig, dass anagram::anagram(...) ein Konstruktor ist, ein Objekt erstellt, die die Methode matches(...) bietet? Weil ich in meiner Implementierung (siehe unten) einen Fehler bekomme, der etwas sagt (nicht in Englisch) wie "Konstruktor kann nicht direkt aufgerufen werden". Ich denke, dass ich etwas über Konstruktoren in C++ nicht verstehe.

// this is part of my implementation of anagram.h 
class anagram{ 

public: 
    anagram(const string a); 
    vector<string> matches(vector<string> &list); 

private: 
    string a; 
    bool isAnagram(string s);  
}; 

Das einzige, was ich weiß, ist, dass anagram::anagram(...) eine statische Methode sein könnte, mit einem Rückgabewert, den similat zu this ist, aber das würde keinen Sinn für mich machen. So wäre es schön, wenn jemand diese :)

+1

'auto subject = Anagramm :: Anagramm (" Windel ");' ist kein gültiger Konstruktoraufruf. –

+0

Es könnte eine Factory-Funktion im Namespace sein. –

+2

Typo; Konstruktoren werden wie 'ClassName (stuff)' oder 'ClassName {stuff}' "aufgerufen". Sie qualifizieren den Anruf nicht als 'CalssName :: ClassName (stuff) – NathanOliver

Antwort

1

Eine Möglichkeit, es mit Syntax arbeiten können Sie gezeigt haben, wenn Klasse anagram in Similary namens Namespace verwendet wird:

#include <string> 
namespace anagram 
{ 
class anagram 
{ 
    public: 
    anagram(std::string s) {} 
}; 
} 

int main() 
{ 
    auto subject = anagram::anagram("diaper"); 
} 

http://ideone.com/1OVhIz

+0

Dies ist irrelevant, da er annahm, dass der Konstruktor von anagram wie jede andere statische Methode aufgerufen werden könnte. – Asu

+1

Macht es überhaupt Sinn, so etwas zu tun? – suffi

+0

Es bietet Ihnen nur die gleiche Syntax wie die, die Sie erwähnt haben, aber es ist nutzlos wortreich, imo. Ohne den Namespace würde man am Ende "Anagramm (" Ding ")" und nicht "Anagramm :: Anagramm (" Ding ")" ... Ich denke nicht, dass es besser ist. edit: besonders unter Berücksichtigung von 'auto thing = anagram :: anagram (" foo ");' ist sogar länger als nur 'anagram :: anagram sache {" foo "};' – Asu

2

erklären könnte, weil Sie von Java kommen, werden Sie verwendet, um etwas zu sehen, ähnlich wie folgt aus:

someobject T = new someObject(argument); 

in C++ eine Klasse in einem anderen Konstrukt weg:

someObject T(argument); 

und tada haben Sie ein Objekt mit dem Namen T in C++ erstellt. eine andere Möglichkeit ist, einen Zeiger auf ein Objekt zu erstellen:

someObject *T = new someObject(argument); 

die mehr ähnlich wie Java, aber jetzt müssen Sie manuell diesen Zeiger löschen. Es ist immer besser, Objekte auf dem Stapel als den Heap zu erstellen. es vermeidet Speicherlecks.


Um Ihre Frage zu beantworten: Sie haben es falsch verstanden. Du rufst Konstruktoren an, wie ich es dir früher gezeigt habe. Sie haben recht, wenn Sie eine statische Memberfunktion aufrufen, aber dies gilt nicht für den Ctor, da er niemals statisch oder virtuell sein kann.

+1

Wenn Sie den Heap in einer Situation verwenden, in der Sie den Stack verwenden können, * kann * manchmal Vorteile haben. Ich hatte einmal eine Situation, in der ich ein großes Array auf dem Stack hatte, das viel schlechter abschnitt als ein 'std :: vector' (der den Heap intern verwendet); wahrscheinlich aus Cache-Gründen. Aber im Allgemeinen konnte ich mehr nicht zustimmen. – Asu

+0

Also ist es eigentlich eine statische Funktion? Aber "Matches" ist immer noch ein Objekt der Klassen-Angram, richtig? – suffi

+0

Ja, aber für was es sich lohnt, den Typ von "Übereinstimmungen" anzugeben würde den Code wahrscheinlich klarer und nicht viel länger machen. Es ist nützlich, wenn Sie lange Namen haben, wie wenn Sie Iteratoren, Tupel usw. handhaben. – Asu

1

Die Syntax aussehen würde tatsächlich eine ähnliche Art und Weise wie in Java (mit Ausnahme für die new, natürlich):

auto subject = Anagram("diaper"); 

Aber es gibt einen einfacheren Weg:

Anagram subject("diaper"); 
Anagram subject{"diaper"}; // C++11 and newer 

auch Sie beachten, dass, wenn Anagram einen Standardkonstruktor hat, wird es aufgebaut sein, wenn Sie es definieren - Es kann nicht null oder so etwas wie in Java, es sei denn Sie * Zeiger verwenden.

Anagram subject; 

Sie können auch eine temporäre Anagram Objekt bauen, so dass Sie nicht über die subject Variable definieren müssen:

auto matches = Anagram{"diaper"}.matches({"hello", "world", "zombies","pants"}); 

Wenn Sie die dynamische Zuordnung verwenden möchten, können Sie new verwenden könnte, aber es isn Kein GC den Wert löschen, wenn Sie nicht mehr brauchen ...!

Anagram* subject = new Anagram("diaper"); 
// ... do some stuff with subject... 
delete subject; // Destroy the dynamically allocated subject and deallocate it 

Wenn Sie jemals die dynamische Speicherzuordnung verwenden möchten, würde ich Ihnen empfehlen, intelligente Zeiger zu verwenden, die Sie auf dieser cpprefrence page finden. Sie haben viele Vorteile gegenüber der manuellen Speicherzuweisung.

2

Wenn der Anruf anagram::anagram muss anagram arbeiten, ist ein Namensraum im Inneren eine Funktion anagram aufgerufen wird, definiert ein Objekt zurück, auf dem Sie eine Methode matches anrufen:

namespace anagram { 
    SomeType anagram(string n) { return SomeType(n); } 
}; 

, die auch ein Klassenname sein könnte anagram innerhalb eines Namensraums anagram.

Dies könnte keine statische Methode sein, da keine Methode außer ctors den Namen der Klasse als Bezeichner verwenden kann.

+0

+1 das ist es, aber ich denke @revolver_ocelot war ein wenig schneller, obwohl ich nicht verstand, was er zuerst sagte, danke! :) – suffi

+0

Gern geschehen! –

Verwandte Themen