tomaschku
Goto Top

Struct macht Probleme, wenn in externe Dateien aufgeteilt

Hallo Leute!

Momentan erliege ich dem Problem, dass mein Code in C++ zwar funktioniert, wenn ich aber mein struct jeweils in Header bzw. CPP Dateien verschiebe, dann gibt es Probleme:

Main.cpp:
#include <Windows.h>
#include <ctime>
#include "Logic.h" 

int main() {
	srand(static_cast<int>(time(NULL)));

        //Unwichtiger Testcode
	return 0;
}

Logic.h:
#pragma once
#ifndef LOGIC_H
#define LOGIC_H

typedef bool bit;

struct Logic {
public:
	bit get();

	void set(bit New);
	void setRandom();
	void Toggle();

	void NOT(bit New);
	void AND(bit A, bit B);
	void OR(bit A, bit B);
	void NAND(bit A, bit B);
	void NOR(bit A, bit B);
	void XOR(bit A, bit B);
	void XNOR(bit A, bit B);
private:
	bit Value = false;
};
#endif {{comment_single_line_double_slash:0}}

Logic.cpp:
#include <windows.h>
#include "Logic.h" 

typedef bool bit;

struct Logic {
public:
	bit get() { return Value; };

	void set(bit New) { Value = New; };
	void setRandom() { Value = rand() > (RAND_MAX / 2); };
	void Toggle() { Value = !Value; };

	void NOT(bit New) { Value = !New; };
	void AND(bit A, bit B) { Value = A & B; };
	void OR(bit A, bit B) { Value = A | B; };
	void NAND(bit A, bit B) { Value = !(A & B); };
	void NOR(bit A, bit B) { Value = !(A | B); };
	void XOR(bit A, bit B) { Value = A ^ B; };
	void XNOR(bit A, bit B) { Value = !(A ^ B); };
private:
	bit Value = false;
};

Trotz dieser Seite komme ich nicht darauf, was ich falsch gemacht habe, denn der Fehler ist folgender:
Fehler | Beschreibung | Datei | Zeile
C2011 | "Logic": "struct" Typneudefinition | logic.cpp | 6

Ich weiß zwar, wieso er den Fehler ausspuckt (Beschreibung), aber verstehe nicht, wie ich den Fehler behebe.


P.s.: [PERSÖNLICHE MEINUNG]Ich habe structs und classes nie so richtig gemocht, eben wegen diesen Problemen, die mit normalen Funktionen nicht wären.[/PERSÖNLICHE MEINUNG]

Gruß,
tomaschku

Content-ID: 368963

Url: https://administrator.de/contentid/368963

Ausgedruckt am: 24.11.2024 um 17:11 Uhr

rubberman
Lösung rubberman 22.03.2018 um 20:13:24 Uhr
Goto Top
In deine Implementation (.cpp) gehören die Definitionen der Memberfunktionen. Dass sie zum struct gehören, wird durch den Name des structs und einem doppelten Doppelpunkt festgelegt.
bit Logic::get() {
  return Value;
}
Also, nicht noch einmal das struct drum herum bauen, denn die Deklaration steht ja schon im Header.
Deinen bit Typ auch nicht noch einmal definieren!
Achtung! Ein bool ist kein Bit! Und ein einzelnes Bit lässt sich auch nicht adressieren. Ich bin mir nicht sicher ob dein Konstruktion überhaupt tut, was sie soll.

Ich habe structs und classes nie so richtig gemocht
Haha, dann bist du mit C++ aber an die falsche Sprache geraten. Gerade der Fakt, dass C++ objektorientiert ist, macht diese Sprache aus ...

Steffen
tomaschku
tomaschku 22.03.2018 um 21:11:54 Uhr
Goto Top
In deine Implementation (.cpp) gehören die Definitionen der Memberfunktionen. Dass sie zum struct gehören, wird durch den Name des structs und einem doppelten Doppelpunkt festgelegt.
Achso, also einfach die Funktionen einzeln deklarieren. Und ich dachte, das wäre bloß optional. Na wenigstens funktioniert es jetzt.

Deinen bit Typ auch nicht noch einmal definieren!
Welche Folgen hat das den? Visual Studio ist das wurscht, also...

Achtung! Ein bool ist kein Bit! Und ein einzelnes Bit lässt sich auch nicht adressieren.
Ich dachte, weil bool nur true/false hat, es würde als Bit dargestellt, aber meinst du mit adressieren Pointer?

Ich bin mir nicht sicher ob dein Konstruktion überhaupt tut, was sie soll
Inwiefern? Ich hab eine Variable vom Typ Logic, der die Ergebnisse der Funktionen annimmt.

Haha, dann bist du mit C++ aber an die falsche Sprache geraten. Gerade der Fakt, dass C++ objektorientiert ist, macht diese Sprache aus ...
Ich dachte das wäre Java? Oder verwechsle ich C++ mit C? Ich hab lange nicht kapiert, was dass mit den private, public,... soll, deswegen habe ich sie nie verwendet. Dies war mein erster (gescheiterter?) Versuch. face-monkey
rubberman
rubberman 22.03.2018 aktualisiert um 22:18:15 Uhr
Goto Top
Welche Folgen hat das den? Visual Studio ist das wurscht, also...
Also eine Warnung, dass ein Typ doppelt definiert ist, hätte ich da mindestens erwartet. Immerhin ist er im Logic.h Header bereits definiert, der in Logic.cpp includiert ist. Also ist der Typ bei der erneuten Definition dort bereits bekannt.

Ich dachte, weil bool nur true/false hat, es würde als Bit dargestellt, aber meinst du mit adressieren Pointer?
Ich denke nicht, dass der C++ Standard irgendetwas darüber aussagt, mit welcher Breite ein bool im Speicher liegt, aber ein sizeof(bool)ergibt bei mir 1. Da sizeof die Breite in Bytes ermittelt, bedeutet das, dass ein bool in meiner Implementation (gcc auf Windows) 8 Bit breit ist.
Mit adressieren meine ich den Zugriff auf ein einzelnes Bit. Ja, im Grunde ist das mit einem Pointer vergleichbar. Speicheradressen gibt es nur im Abstand der kleinsten adressierbaren Einheit. In C und C++ ist das ein char, das in allen gängigen Implementationen (Windows, Mac, Linux, UNIX, Android, ...) 8 Bit breit ist. Wenn du innerhalb eines char auf ein einzelnes Bit zugreifen willst, dann geht das nur über bitweise Operationen (wie & | >> ~ etc).
C++ hat allerdings den (nicht besonders gut gelungenen) Versuch gewagt, boolesche Werte als Bits abzulegen, und zwar in dem gesondert implementierten vector<bool>. Genau die Tatsache dass nicht direkt auf ein einzelnes Bit zugegriffen werden kann, macht diese Implementation aber zur Falle bei performance-kritischen Codes. Es sind einfach zu viele Operationen nötig. Und es ist ja nun wirklich nicht so, als würde es noch eine Rolle spielen ob ein bool 1, 8, oder 32 Bit breit dargestellt wird. Wir sind nicht mehr in den 1980-ern, wo der zur Verfügung stehende Arbeitsspeicher gegen 0 tendiert ist face-wink

Inwiefern?
Keine Ahnung, habe nicht versucht deinen Code zu kompilieren oder tiefgründiger zu untersuchen. Der Grund ist, wie oben beschrieben, dass dein bit Typ eigentlich 8 Bit breit ist.

Ich dachte das wäre Java? Oder verwechsle ich C++ mit C?
Java, C++, C#, ... Alle objektorientiert. Und ja, vermutlich verwechselst du das mit C. Solltest du aber nicht, denn C und C++ sind zwei Sprachen die nicht unterschiedlicher sein könnten. Nur weil C++ irgendwann mal aus C heraus entwickelt wurde und weil die C Lib aus Kompatibilitätsgründen fast vollständig in C++ aufgeht, werden C und C++ immer irgendwie in einem Atemzug genannt. Für mich völlig unverständlich ...

Ich hab lange nicht kapiert, was dass mit den private, public,... soll, deswegen habe ich sie nie verwendet.
Ein gutes Buch, mit dem man die Sprache von Grund auf lernt, schafft Klarheit.

Steffen
tomaschku
tomaschku 23.03.2018 um 16:23:50 Uhr
Goto Top
Also eine Warnung, dass ein Typ doppelt definiert ist, hätte ich da mindestens erwartet. Immerhin ist er im Logic.h Header bereits definiert, der in Logic.cpp includiert ist. Also ist der Typ bei der erneuten Definition dort bereits bekannt.
Muss ich schauen, ob ich das nicht umgestellt habe.

Ich denke nicht, dass der C++ Standard irgendetwas darüber aussagt, mit welcher Breite ein bool im Speicher liegt,...
Ich hab es als Bit bezeichnet, damit ich am einfachsten arbeiten kann. Ist aber Interessant zu wissen.

Java, C++, C#, ... Alle objektorientiert. Und ja, vermutlich verwechselst du das mit C. Solltest du aber nicht, denn C und C++ sind zwei Sprachen die nicht unterschiedlicher sein könnten. Nur weil C++ irgendwann mal aus C heraus entwickelt wurde und weil die C Lib aus Kompatibilitätsgründen fast vollständig in C++ aufgeht, werden C und C++ immer irgendwie in einem Atemzug genannt. Für mich völlig unverständlich ...
Ist wahrscheinlich Gewohnheitssache, wie bei mir. Ich dachte, der Begriff "objektorientiert" bedeutet 'bloß', dass man auch mit Objekten arbeiten kann, +- als Addon.

Ein gutes Buch, mit dem man die Sprache von Grund auf lernt, schafft Klarheit.
Möchte ich auch, aber ich versuche es so lange wie möglich ohne auszukommen, denn Bücher verstauben bei mir leider schnell. face-smile
rubberman
rubberman 23.03.2018 um 17:59:13 Uhr
Goto Top
Ist wahrscheinlich Gewohnheitssache, wie bei mir. Ich dachte, der Begriff "objektorientiert" bedeutet 'bloß', dass man auch mit Objekten arbeiten kann
Im Fall von C++ ist das tatsächlich ein "kann". Du musst dir aber bewusst sein, dass du bereits die ganze Zeit mit Objekten arbeitest. Heißt ja nicht, dass du die Implementation selber vorgenommen hast. Z.B. ist cout eine Instanz der ostream Klasse und cin eine Instanz der istream Klasse. Alles was du aus der C++ STL nutzt, sind im Zweifelsfall Klassen, wie string, Containertypen, Iteratoren, Exceptions und und und ...

Steffen
tomaschku
tomaschku 23.03.2018 um 18:47:48 Uhr
Goto Top
Ok, Danke für die Information.

tomaschku