11 Stimmen

Statische Konstante double in C++

Ist dies der richtige Weg, um eine statische konstante Variable zu verwenden? In meiner Top-Level-Klasse (Shape)

#ifndef SHAPE_H
#define SHAPE_H

class Shape
{
public:

    static const double pi;
private:
    double originX;
    double originY;
};

const double Shape::pi = 3.14159265;

#endif

Und dann später in einer Klasse, die Shape erweitert, verwende ich Shape::pi. Ich erhalte einen Linker-Fehler. Ich habe die const double Shape::pi = 3.14... in die Datei Shape.cpp verschoben und mein Programm lässt sich dann kompilieren. Warum passiert das? Danke.

13voto

Benjamin Punkte 2920

Wenn Sie eine Möglichkeit haben, die C++11 (oder später) an Ihren Compiler übergeben, hätten Sie das auch tun können:

ifndef SHAPE_H
#define SHAPE_H

class Shape
{
public:

    static constexpr double pi = 3.14159265;
private:
    double originX;
    double originY;
};

#endif

Desde C++11 können Sie const-Ausdrücke für andere als ganzzahlige Typen verwenden. Auf diese Weise können Sie Ihre konstante Variable an Ort und Stelle deklarieren und definieren.

Weitere Einzelheiten: https://en.cppreference.com/w/cpp/language/constexpr

12voto

R Samuel Klatchko Punkte 72641

Denn const double Shape::pi = 3.14159265; ist die Definition von Shape::pi und C++ erlaubt nur eine einzige Definition eines Symbols (genannt Eine-Bestimmung-Regel die Sie vielleicht in der abgekürzten Form ODR sehen). Wenn die Definition in der Header-Datei steht, erhält jede Übersetzungseinheit ihre eigene Definition, was diese Regel bricht.

Wenn Sie sie in die Quelldatei verschieben, erhalten Sie nur eine einzige Definition.

12voto

Potatoswatter Punkte 130562

Statische Fließkomma-Datenelemente müssen in einer Quelldatei definiert und initialisiert werden. Die Ein-Definitions-Regel verbietet eine Definition außerhalb der class {} Block in der Kopfzeile, und nur integrale Datenelemente dürfen innerhalb des Blocks initialisiert werden. class {} Block.

Dies ist auch deshalb bedauerlich, weil es sich um einen algebraischen Wert handelt und es für die Optimierung von Vorteil sein könnte, den unmittelbaren Wert zur Hand zu haben, anstatt ihn aus einer globalen Variablen zu laden. (Der Unterschied dürfte allerdings unerheblich sein.)

Aber es gibt eine Lösung!

class Shape
{
public:
    static double pi()
        { return 3.14159265; }

private:
    double originX;
    double originY;
};

Inline-Funktionsdefinitionen, einschließlich statischer Funktionen, sind innerhalb der class{} Block.

Ich empfehle auch die Verwendung von M_PI de <math.h> , die Sie auch von <cmath> .

3voto

Joseph Lisee Punkte 3365

Das passiert, weil man Shape::pi nicht mehr als einmal definieren kann. Es wird einmal definiert, wenn Sie Shape.h in Shape.cpp einbinden, und dann jedes Mal wieder, wenn Sie Shape.h in einer anderen cpp-Datei verwenden. Beim Linken des Programms kotzt der Linker wegen der Mehrfachdefinitionen.

1voto

zmbush Punkte 2764

Die Linie const double Shape::pi = 3.14159265; sollte in Ihrer Datei Shape.cpp enthalten sein. Die Header-Datei dient zur Deklaration der Variablen. Sie können eine Variable nur einmal definieren, daher muss dies in der Datei .cpp . Die Header-Datei sagt, wie diese Variablen und Funktionen zu verwenden sind, die cpp-Datei sagt, was zu tun ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X