我的IDE是Microsoft Visual Studio 2017。
这是原始示例代码:
main.cpp
#include <iostream>
#include "Klasa_00.h"
using namespace std;
int main() {
int const Number_0 = 234;
float const Number_1 = 34.76;
double const Number_2 = 98.78;
cout << "Number_0 is:" << Number_0 << endl;
cout << "Number_1 is:" << Number_0 << endl;
cout << "Number_2 is:" << Number_0 << endl;
system("Pause");
return 0;
}
Klasa_0.cpp
#include "Klasa_00.h"
Klasa_00::Klasa_00()
{
}
Klasa_00::~Klasa_00()
{
}
Klasa_0.h文件
#pragma once
class Klasa_00
{
public:
Klasa_00();
~Klasa_00();
};
我是C ++编程的新手,所以我需要有关编写代码的帮助。例如,在Fortran编程语言中,具有参数属性的所有变量都可以在单独的模块中声明,可以在主程序中轻松使用。
我想在这里学习的是在C ++或类似语言中使用这种编码原理的可能性。
因此,在我的案例中,我有三个变量要移入类Klasa_00
中。
有这样做的方法吗?
答案 0 :(得分:1)
为什么您需要为此上课?这似乎不合适。由于C ++是另一种语言,具有不同的习惯用法和概念,因此FORTRAN比较也不大可能取得成果。
在我看来,您应该将这些常量简单地放在头文件中。确保将它们设置为static const constexpr
,以避免链接程序冲突。
// Constants.hpp
#ifndef MYLIB_CONSTANTS_HPP
#define MYLIB_CONSTANTS_HPP
#pragma once
static constexpr const int Number_0 = 234;
static constexpr const float Number_1 = 34.76;
static constexpr const double Number_2 = 98.78;
#endif
现在,您只需#include "Constants.hpp"
在任何需要访问这些值的翻译单元中即可。
根据记录,做相同事情的老式C方法是使用#define
。
别忘了给这些常量赋予有意义的名称。
答案 1 :(得分:1)
正如其他人所说,您可能希望避免使用类将常量存储在其他文件中,而您可能只是希望将它们存储在标头中(可能带有名称空间,稍后再介绍)。话虽如此,我确实知道您可能想要一个属于一个类的常量,因此在答案的稍后部分,我还将对此进行介绍。
最简单的方法是这样声明和定义标头中的常量:
// YourHeader.h
#ifndef YOUR_HEADER_H
#define YOUR_HEADER_H
[...]
const int aConstNumber = 1;
static const int anotherConstNumber = 2;
constexpr int aConstExprNumber = 3;
static constexpr int anotherConstExprNumber = 4;
[...]
#endif
// main.cpp
#include <iostream>
#include "YourHeader.h"
int main()
{
// You can simply access the variables by name as so:
std::cout << aConstNumber << "\n"; // 1
std::cout << anotherConstNumber << "\n"; // 2
std::cout << aConstExprNumber << "\n"; // 3
std::cout << anotherConstExprNumber << std::endl; // 4
}
这些变量在逻辑上都具有相同的行为,但是它们以不同的方式工作。使用const
关键字声明的变量是在运行时定义的,并且保证不会更改。但是,使用constexpr
关键字声明的变量是在编译时定义的。
因此,虽然这意味着如果您有多个类(例如ID)(ID不应更改,但应该是唯一的),则与const
相比,constexpr
更受欢迎(因为后者在这种情况下将无法工作)。
我们也来谈谈static
。 static
表示在您的类中存在该变量的单个共享实例。因此,如果Bar
类具有static int ID
值,则Bar
的所有实例共享相同的ID
值。更改一次即可更改所有实例。尽管如果它是一个常数,则您将不能对其进行更改。
在您的情况下,如果要定义预定义且不会更改的常量,我强烈建议您使用constexpr
,因为您可以使用这些变量来执行无法使用const
变量(例如定义数组的大小)。
在继续进行之前,请考虑以下课程。
class Foo
{
public:
const int a = 5; // Valid use of const.
constexpr int b = 7; // Invalid use of constexpr, won't even compile!
static constexpr int c = 10; // Valid use of constexpr.
int arrA[a]; // ERROR: 'a' is defined at runtime, so you can't use it to define a size.
int arrB[b]; // ERROR: You couldn't even define 'b', so this is not going to work...
int arrC[c]; // VALID: 'c' is known by the compiler, and is guaranteed to only ever be 10!
}
值得注意的是,如果要访问a
或c
(在类中声明和定义的唯一两个有效变量),则必须使用以下语法,而不是只是他们的名字:
// "Foo" is their class' name, and represents their parent namespace.
std::cout << Foo::a << "\n"; // 5
std::cout << Foo::c << std::endl; // 10
如您所见,constexpr int b = 7;
无效。为什么呢它不应该被编译器看到并且可以正常工作吗?好吧,不。您会发现,问题在于您可能永远也不会实例化该类,对吗? const
变量很好,因为它们是在运行时定义的,这意味着它们不必存在,一旦给它们赋值就不能更改。另一方面,constexpr
必须确保它会存在,因为它必须存在并且在编译时才有效!
尽管在头文件中声明一个constexpr
变量是完美的,但是如果要在类中声明一个变量,除非与它一起使用static
关键字,否则它是行不通的!因为static
关键字将使编译器知道,无论您如何实例化此类,变量的值将永远不会改变,并且由于{{1} }!
强烈建议您阅读this post,以了解constexpr
和static
合并后的作用。
constexpr
。 const
。 constexpr
反对,因为它会在运行时定义,但始终具有相同的值, 对?只需使用static const
即可。最后,我在此答案的开头提到了名称空间。有时,您可能需要一组不一定属于一个类的关联常数。例如,虽然PI用于圈子中,但这并不一定意味着我每次想要PI时都想包含static constexpr
类的标头。但是我不想在项目的名称空间中使用“原始” PI变量名称!那只是自找麻烦。相反,可以考虑将常量包围在circle
块中,以模拟用于调用类成员的语法!
namespace
请注意,我们没有将// YourHeader.h
#ifndef YOUR_HEADER_H
#define YOUR_HEADER_H
namespace MyConstants
{
constexpr int a = 1;
constexpr int b = 2;
}
#endif
// main.cpp
#include <iostream>
#include "YourHeader.h"
int main()
{
std::cout << MyConstants::a << "\n"; // 1
std::cout << MyConstants::b << "\n"; // 2
}
与命名空间一起使用,因为我们没有使用static
或class
,所以我们不需要,我们只是将它们包装起来在struct
中,以避免命名冲突。 namespace
在这里会做其他事情。有关更多信息,请参见this post。
额外的注意:虽然可以将变量声明为static
,但我不建议您使用它,因为它的作用与简单地声明constexpr const
相同。请注意,constexpr
与指针结合使用时,会将指针变成指向常量值的常量指针!有关更多详细信息,请参见this post。