第五十七篇:VS2015建立一个完整的c++工程:头文件.h 源文件.cpp,自动生成类

本文介绍如何使用Visual Studio 2015创建并管理C++多文件项目,包括类的定义、构造函数及成员函数的实现等关键步骤。详细展示了从新建项目到添加源文件、头文件的过程,以及类的定义和实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前没有用VS或者在vs中一个源程序写到底,没有使用C++编一个工程

打开VS2015 ,新建VS win32工程,前面步骤很简单,不再阐述

下面直接开始:

新建一个VC++ win32的程序,

在源文件加下添加.cpp文件,一般放main函数

#include <iostream>
#include <locale>
#include "human.h"
using namespace std;


int main()
{
Human Tom;
Tom.A(160);
people zhangsan;
zhangsan.B(160);


//cout<<Tom.printf();
}


在头文件中添加.h文件,一般是定义的类

#include "human.h"

class Human
{
public:
void A(int w);
private:
int *i;
};


class people
{
public:
void B(int j);
int num;
private:
int numa;
};

头文件中的.cpp文件放类的构造函数

#include "human.cpp"


#include <iostream>
#include "human.h"
using namespace std;
void Human::A(int w)
{
cout << w << endl;
}
void people::B(int w)
{
w -= 100;
cout << w << endl;
}


然后在源文件下的main函数的要加上类的声明头文件,头文件.cpp也要添加类声明的头文件

i


注意:头文件中定义的类,在与之同名的c文件中要做声明,类的构造函数和析构函数要么显示定义,也要显示的声明,哪怕这些函数里面没有执行的内容,空的也要写出来,否则会编译通不过,要么类的构造函数和析构函数都不写,类默认产生不执行任何程序的构造函数和析构函数

反正一条:对于类里面的析构函数和构造函数只要定义了,必须要声明,函数为空也可以


下面补充一下在VS里面多文件系统(即有多个头文件和cpp文件),使用VS来自动生成类,

1、项目右击->添加->类

输入类名后,h文件和cpp文件自动填充好,而且生成的类的构造函数、析构函数、包含头文件全都有了

如下图:


生成的代码:

h文件

#pragma once

class Clock
{
public:
	Clock();
	~Clock();
};
cpp文件
#include "Clock.h"

Clock::Clock()
{
}

Clock::~Clock()
{
}


上面都是空的,下面在里面填上我们的函数

2、在类里面放上我们的函数

h文件添加函数后

#pragma once
#include <iostream>
using namespace std;

class Clock
{
public:
	Clock();
	void SetTime(int NewH, int NewM, int NewS);   //三个形参均具有函数原型作用域
	void ShowTime();
	~Clock();
private:
	int Hour, Minute, Second;
};
cpp文件添加函数后

#include "Clock.h"
Clock::Clock()
{
	Hour = 0;
	Minute = 0;
	Second = 0;

}
void Clock::SetTime(int NewH, int NewM, int NewS)
{
	Hour = NewH;
	Minute = NewM;
	Second = NewS;
}
void Clock::ShowTime()
{
	cout << Hour << ":" << Minute << ":" << Second << endl;
}

Clock::~Clock()
{
}

3、在main里面添加我们的类包含头文件

#include "Clock.h"   //头文件
Clock g_Clock;
int main() //主函数
{
	cout << "文件作用域的时钟类对象:" << endl;
	//引用具有文件作用域的对象:
	g_Clock.ShowTime();
	g_Clock.SetTime(10, 20, 30);

	Clock myClock(g_Clock);    //声明具有块作用域的对象myClock,并通过默认拷贝构造函数用g_Clock初始化myClock
	cout << "块作用域的时钟类对象:" << endl;
	myClock.ShowTime(); //引用具有块作用域的对象
	return 0;
}

运行结果:


over!!!




<think>好的,我现在需要帮助用户解决C++中的两个问题:initStorageManager的未定义引用错误和test_assign1_1.c的单页内容失败,退出码-1073740791。首先,我得回顾用户之前的提问和我的回答,确保这次回答一致且全面。 第一个问题,undefinedreference toinitStorageManager,这通常是链接器错误,说明函数声明了但没找到实现。用户可能没有正确链接源文件或库。我之前提到过检查声明与定义是否一致,确保storage.cpp被编译并链接到项目中。现在需要再次确认这些步骤,并考虑其他可能性,比如名称修饰问题,特别是如果混合使用了C和C++代码,可能需要extern"C"。第二个问题,test_assign1_1.c的单页内容失败,退出码-1073740791。这个错误码可能与访问冲突有关,比如内存错误、栈溢出或空指针。需要分析测试用例中的代码,检查内存管理是否正确,是否有越界访问或未初始化的指针。接下来,我需要将这两个问题分开处理,但也要考虑它们是否有联系。比如,存储管理器初始化失败可能导致后续测试中的内存错误。因此,先解决链接错误可能有助于第二个问题。对于undefinedreference错误,可能的解决方案包括:1.确保storage.cpp被添加到项目中并编译。2.检查函数签名是否完全一致,包括参数和返回型。 3.使用extern"C"来避免C++的名称修饰,特别是如果测试用例是C代码调用C++函数。4.确认链接器是否包含生成的obj文件或库。 对于退出码-1073740791,可能的解决步骤:1.使用调试器(如Visual Studio的调试工具)定位崩溃位置。 2.检查内存操作,如数组越界、野指针、双重释放。3.确保存储管理器正确初始化,避免使用未初始化的资源。 4.检查栈大小,是否有递归过深或大局部变量导致栈溢出。 需要提醒用户检查存储管理器初始化的相关代码,确保在测试用例中正确调用了initStorageManager,并且该函数正确初始化了必要的资源。如果初始化失败,后续操作可能导致内存错误。另外,用户提到的test_assign1_1.c是C文件,而initStorageManager可能是C++实现的,这时候必须使用extern"C"来确保C代码能正确链接到C++函数,否则会出现名称修饰不一致的问题,导致链接错误。最后,生成相关问题时要围绕这两个问题展开,可能涉及内存管理、链接配置、调试技巧等。</think>### C++存储管理器初始化错误与测试失败解决方案 --- #### 一、`initStorageManager`未定义引用错误分析 1. **符号可见性验证** - 检查函数声明与定义是否严格一致: ```cpp // storage.h (头文件) #ifdef __cplusplus extern "C" { // 强制C语言链接规范[^1] #endif void initStorageManager(void); // C风格无参数声明 #ifdef __cplusplus } #endif ``` ```cpp // storage.cpp (实现文件) #include "storage.h" void initStorageManager() { // 必须严格匹配声明 // 初始化内存池等操作 } ``` - 使用`dumpbin /symbols storage.obj`验证符号名称是否包含`_initStorageManager`(注意C与C++符号差异) 2. **编译系统配置** - 确保`storage.cpp`参与编译流程: - Visual Studio中右键解决方案资源管理器 > 生成依赖项 > 自定义生成 - 检查编译输出是否生成`storage.obj` - 链接器设置验证: | 配置项 | 正确值示例 | |----------------------|-------------------------| | 附加库目录 | $(ProjectDir)\objs | | 附加依赖项 | storage.obj | --- #### 二、测试用例崩溃问题(退出码`-1073740791`) 1. **错误码解析** - `0xC0000409` (STATUS_STACK_BUFFER_OVERRUN) 表示栈缓冲区溢出,常见原因: - 局部数组越界访问:`char buf[10]; buf[20] = 0;` - 未初始化指针:`int* p; *p = 5;` - 递归深度过大导致栈耗尽 2. **调试步骤** - 启用调试工具: ```cpp // test_assign1_1.c #include <windows.h> int main() { __debugbreak(); // 插入调试断点 initStorageManager(); // 测试代码 } ``` - 在Visual Studio中: 1. 按`F5`启动调试 2. 查看"调用堆栈"窗口定位崩溃位置 3. 检查"局部变量"窗口中的数组索引和指针值 3. **内存分析工具** - 使用AddressSanitizer(VS2019+支持): ```cmake # CMakeLists.txt add_compile_options(/fsanitize=address) add_link_options(/fsanitize=address) ``` - 检测到错误时会输出详细堆栈信息,例如: ``` ==42==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffd4a6cf010 ``` --- #### 三、关联问题排查 1. **存储管理器与测试用例的依赖关系** - 验证初始化顺序是否正确: ```cpp // 错误示例:未初始化直接使用 extern StorageManager* g_manager; // 全局变量 void test_case() { g_manager->allocate(100); // 可能访问空指针 } ``` - 正确模式: ```cpp int main() { initStorageManager(); // 必须先执行 run_tests(); return 0; } ``` 2. **跨语言调用规范** - 当C++实现的`initStorageManager`被C代码调用时,必须使用`extern "C"`: ```cpp // storage.h #ifdef __cplusplus extern "C" { // 确保C编译器可见[^2] #endif void initStorageManager(); #ifdef __cplusplus } #endif ``` --- #### 四、验证代码示例 ```cpp // storage.cpp (完整实现示例) #include "storage.h" #include <vector> static std::vector<void*> memory_pool; extern "C" void initStorageManager() { memory_pool.reserve(1024); // 预分配内存 } extern "C" void* sm_malloc(size_t size) { void* ptr = malloc(size); memory_pool.push_back(ptr); return ptr; } ``` ```c // test_assign1_1.c (修复后的测试用例) #include "storage.h" #include <stdio.h> int main() { initStorageManager(); int* arr = (int*)sm_malloc(10 * sizeof(int)); for(int i=0; i<10; i++) { // 严格限制循环次数 arr[i] = i; } return 0; } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值