我拿起了 Bjarne Stroustrup 的书《使用 C++ 进行编程原理和实践》(第三版),但我还没有深入了解第 2 章。我在 PC 上使用 Visual Studio 2020 (v143)。 我做了一切来建立一个项目(
Ch2_Fmletter
),包括PPP.h
、PPP_support.h
和PPP.ixx
。 我还完成了 Stroustrup 推荐的所有项目属性设置在他的网站上:
微软C++
使用 Visual Studio 时。
- 模块文件后缀为.ixx
- 设置项目的属性[原文如此]。选项卡:项目 -> 项目名称。
- 常规属性:将“C++语言标准”设置为“最新”
- C/C++ 常规:扫描其他模块依赖项:“是”
在我的项目中,我还包含头文件
PPP.h
和 PPP_support.h
以及资源文件(模块)PPP.ixx
。
从 来自编程原理与实践 3ed 指令不清楚的支持信息,我在 Stroustrup 的
PPP_support.h
文件中找到了有关错误的信息,并通过向 simple_error() 函数添加 std::
进行了必要的更正,如下所示:
PPP_EXPORT inline void simple_error(std::string s) // write ``error: s'' and exit program (for non-exception terminating error handling)
{
std::cerr << "error: " << s << '\n';
exit(1);
}
现在我又出现了另一个烦人的错误,但程序将编译并运行! 实际上出现了 3 个错误,但我想如果我修复了第一个错误,其他错误就会消失。 错误代码为 E0070:不允许不完整的类型“PPP::Checked_string”。
我的
Ch2_Fmletter.cpp
文件中的源代码非常简单:
#include "PPP.h"
int main()
{
cout << "Please enter your first name (followed by 'enter'):\n";
string first_name; // first_name is a variable of type string
cin >> first_name; // read characters into first_name
cout << "Hello, " << first_name << "!\n";
}
模块
PPP.ixx
包括 #include "PPP_support.h"
。
错误代码“E0070:不完整类型”指向变量first_name的定义:
string first_name;
将鼠标悬停在first_name上,Visual Studio IntelliCode向我显示:
根据一些对附加信息的请求,我显示了项目构建的屏幕截图,除了 IntelliCode (IntelliSense) 显示的内容之外,您还可以看到列出的错误:
其中一个包含的头文件是
PPP.h
,由于它很短,因此在下面复制。 我不明白 #define 语句,但 Stroustrup 的评论说它们是 "disgusting macro hack"
// PPP.h
import PPP;
using namespace PPP;
using namespace std;
// disgusting macro hack to guarantee range checking for []:
#define vector Checked_vector
#define string Checked_string
#define span Checked_span
调用进行范围检查的实际源代码位于
PPP_support.h
,该文件可在此处找到:链接到 PPP_support.h
困难似乎在于class Checked_string
。
我也处于同样的情况(CPP 初学者,正在学习这本入门教材)。 我能够按照上面的方式运行代码,但在涉及字符串连接的后续步骤中失败了:
#include "PPP.h"
int main()
{
cout << "Hello\n";
string first;
string second;
cin >> first >> second;
//string name = "";
string name = first + " " + second;
cout << "Hello, " << name << "\n";
}
虽然我无法摆脱错误消息“不允许不完整的类型“PPP::Checked_string””,但我至少能够通过修改 PPP_support 中“Checked String”的定义来构建和运行此代码.h:
PPP_EXPORT class Checked_string : public std::string {
public:
using std::string::string; // Inherit constructors
// Default constructor
Checked_string() : std::string() {}
// Constructor to accept std::string
Checked_string(const std::string& s) : std::string(s) {}
// Implicit conversion to std::string
operator std::string() const {
return std::string(*this);
}
// Overloaded subscript operator with range checking
char& operator[](size_t i) {
std::cerr << "PPP::string::[]\n";
return this->std::string::at(i);
}
const char& operator[](size_t i) const {
std::cerr << "PPP::string::[] const\n";
return this->std::string::at(i);
}
};
我不太明白为什么这样做会起作用,但它至少让我在这本初学者入门教科书的第 2 章中取得了进展。