我编写了一个简单的程序,它使用带有构造函数、析构函数和数据成员的类。当我尝试初始化一个对象时,调试器告诉我没有析构函数和析构函数。我在Clion、VS2019和VSCode中尝试过。我得到了与 4) 相同的结果。我不知道当我实际创建构造函数和析构函数时它总是发生。
请帮助我。谢谢!
1) String.h
#ifndef TEST_STRING_H
#define TEST_STRING_H
class String {
public:
explicit String(const char *cstr = nullptr);
String(const String &str);
String &operator=(const String &str);
~String();
char *get_c_str() const { return m_data; }
private:
char *m_data;
};
#endif // TEST_STRING_H
2) String.cpp
#include "String.h"
#include <cstring>
inline String::String(const char *cstr) {
if (cstr) {
m_data = new char[strlen(cstr) + 1];
strcpy(m_data, cstr);
} else {
m_data = new char[1];
*m_data = '\0';
}
}
inline String::~String() { delete[] m_data; }
inline String &String::operator=(const String &str) {
if (this == &str)
return *this;
delete[] m_data;
m_data = new char[strlen(str.m_data) + 1];
strcpy(m_data, str.m_data);
return *this;
}
inline String::String(const String &str) {
m_data = new char[strlen(str.m_data) + 1];
strcpy(m_data, str.m_data);
}
3) main.cpp
#include <iostream>
#include "String.h"
using namespace std;
int main() {
String s1("hello");
return 0;
}
4)结果
/tmp/ccCIK0hs.o: In function `main':
/home/Projects/test/main.cpp:7: undefined reference to `String::String(char const*)'
/home/Projects/test/main.cpp:7: undefined reference to `String::~String()'
collect2: error: ld returned 1 exit status
最佳答案
您使用inline
说明符的方式存在“问题”。修复方法只是从所有 String
方法定义中删除 inline
说明符,以使错误消失。
让我们深入研究一下为什么你的程序格式错误。
我将使用 cppreference inline specifier 中的积分:
An inline function or inline variable (since C++17) has the following properties:
- The definition of an inline function or variable (since C++17) must be reachable in the translation unit where it is accessed (not necessarily before the point of access).
- An inline function or variable (since C++17) with external linkage (e.g. not declared static) has the following additional properties:
- There may be more than one definition of an inline function or variable (since C++17) in the program as long as each definition appears in a different translation unit and (for non-static inline functions and variables (since C++17)) all definitions are identical. For example, an inline function or an inline variable (since C++17) may be defined in a header file that is #include'd in multiple source files.
- It must be declared inline in every translation unit.
- It has the same address in every translation unit.
Ad 1) 简而言之:如果您有一个内联函数定义,如 inline String::String(const char *cstr) { some }
,您可以从同一个 .cpp
文件调用它。如果您从其他 .cpp
文件调用它,就像您在 String.cpp
中定义函数但从 main.cpp
调用它一样,这是无效的。
广告 2) 您的函数不是静态的,因此本节适用。
Ad 2.1) 如果您的 String.cpp
中有 inline String::String(const char *cstr)
,则 String.h
的类声明中必须有 inline String::String(const char *cstr);
。如果您使用 inline
声明它,则它在任何地方都必须是 inline
,在 String.h
中也是如此。现在在您的代码中,String.h
中没有内联
。
解决方法是遵守 1
和 2.1
中的规则。因此,要么从 String.cpp
中删除 inline
关键字,然后让所有函数只是具有外部链接的普通函数,这是正常的编程方式。
或者,如果您必须让函数具有 inline
功能,请将所有代码从 String.cpp
移动到 String.h
并将 inline
添加到这些成员函数声明中。就像下面的代码:
#ifndef TEST_STRING_H
#define TEST_STRING_H
class String {
public:
inline explicit String(const char *cstr = nullptr);
inline String(const String &str);
inline String &operator=(const String &str);
inline ~String();
inline char *get_c_str() const { return m_data; }
private:
char *m_data;
};
#include <cstring>
inline String::String(const char *cstr) {
if (cstr) {
m_data = new char[strlen(cstr) + 1];
strcpy(m_data, cstr);
} else {
m_data = new char[1];
*m_data = '\0';
}
}
inline String::~String() { delete[] m_data; }
inline String &String::operator=(const String &str) {
if (this == &str)
return *this;
delete[] m_data;
m_data = new char[strlen(str.m_data) + 1];
strcpy(m_data, str.m_data);
return *this;
}
inline String::String(const String &str) {
m_data = new char[strlen(str.m_data) + 1];
strcpy(m_data, str.m_data);
}
#endif // TEST_STRING_H
请注意,“在类定义内部”定义的函数是隐式内联
的,因此您也可以将函数定义移动到类定义内部。
关于c++ - 如何解决对自己类的构造函数和析构函数的 undefined reference 的问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59930828/