grundlegendes Verständnisproblem: namespace-Verwendung mit 2 Dateien ohne Header
-
Ad aCTa schrieb:
Ich verstehe nicht, wieso du auf Header verzichten willst, es geht aber natürlich auch ohne, mit extern:
[...][...] namespace XY { extern int test(); } [...]Das
externist hier überflüssig. eine Funktionsdeklaration in einem nicht-anonymen Namensraum führt automatisch schon einen Namen (hier "test") mit externer Bindung (external linkage) ein.Peter, Du vermischst hier verschiedene Konzepte, die nicht viel miteinander zu tun haben. Namensräume sind total unabhängig davon, wo und wie Quellcode gespeichert wird (im Gegensatz zu den Java Packages zum Beispiel). Das Konzept einer Übersetzungeinheit und was
#includeeigentlich macht, solltest Du Dir auch nochmal angucken. "Header-Dateien" sind auch nichts Besonderes. Den Compiler interessiert es nicht die Bohne, woher der Quellcode kommt. Das mit den Header-Dateien ist nur eine Konvention, die sich entwickelt hat -- eine gute Konvention. Ein anderes wichtiges Konzept ist die Bindung (linkage).In jedem guten C++ Buch sollte das alles geklärt werden. Man kann sich echt viel Zeit und Ärger sparen, wenn man das einfach mal nachließt. Ich weiß ja nicht, wie's Euch geht/ging, aber ich fand das höchst unbefriedigend, nicht den Durchblick bzgl Header, Namensräume, Bindung, "One-Definition-Rule", ... zu haben.
Gruß,
SP
-
Ad aCTa schrieb:
Ich verstehe nicht, wieso du auf Header verzichten willst, es geht aber natürlich auch ohne, mit extern:
namespace XY { int test() { return 4; } }#include <iostream> using namespace std; namespace XY { extern int test(); } int main() { cout << XY::test() << endl; cin.get(); return 0; }Du musst den Namespace in beiden Dateien definieren, die Funktion muss mit extern deklariert werden, dann weiß der Compiler, dass sich der Linker darum kümmern muss, die Funktion zu finden.
Danke, jetzt klappt es!
Nochmal, bevor einige hier nicht schlafen können

Ich weiß, dass ich eine Header-Datei benutzen sollte, aber als es klappte war da diese Neugier, ob ich das auch ohne kann, so als Beweis. Und wie ihr seht konnte ich das nicht, also waren da wohl noch Lücken!Gerade für OOP sind explizite Schnittstellen ja durchaus eine sinnvolle Sache

Danke allen!
-
unskilled schrieb:
...
int main() { /*...*/ return 0; //brauchst du nicht }edit - also so:
/*main.cpp*/ #include "foo.h" int main() { my::foo(); }...
Naja - ich nutze trotzdem sehr gerne ein "überflüssiges return", weil
a) es sowieso nur bei main und 0 funktioniert (ist mir schon mehr als einmal passiert, dass main() später zu einer anderen Funktion wurde)
b) es üblicherweise sowieso eine meiner ersten Überlegungen ist, wann eine Funktion was zurückliefern soll; da wird das Weglassen eher zu einem künstlichen "Kunsttrick".Aber es stimmt natürlich: Man darf es weglassen (und Viele wissen das nicht).
Gruß,
Simon2.
-
warum erlaubt der Compiler das denn, wenn ich als Signatur auch
main():voidbenutzen kann?
-
PeterFragt schrieb:
warum erlaubt der Compiler das denn, wenn ich als Signatur auch
main():voidbenutzen kann?
Falls Du
void main();meinst: Weil er auch nicht standardkonforme Dinge zulässt (und sie "irgendwie" interpretiert).
Gruß,
Simon2.