将类作为主要参数的语法在哪里需要?

Where is the syntax with class as a parameter in main needed?

本文关键字:语法 在哪里 参数      更新时间:2023-10-16

这个问题指出,main可以用一些限制来定义实现。 因此,我编写了以下C++代码来尝试以下main签名:

主H

class MyClass {
private:
int i;
public:
MyClass();
inline int geti() {
return i;
}
inline void seti(int i)  {
this->i = i;
}
~MyClass();
};
MyClass::MyClass() {
this->i = 2;
}
MyClass::~MyClass() {
}

main.c++

#include <iostream>
#include "main.h"

int main(MyClass myClass) {
std::cout << myClass.geti() << std::endl; 
return 0;
}

给出以下结果:

命令g++ -o main main.c++ -O3成功编译,但出现警告:

main.c++:5:5: warning: first argument of ‘int main(MyClass)’ should be ‘int’ [-Wmain]
5 | int main(MyClass myClass) {
|     ^~~~
main.c++:5:5: warning: ‘int main(MyClass)’ takes only zero or two arguments [-Wmain]

命令clang++ -o main main.c++ -std=c++14给出错误:

main.c++:5:5: error: first parameter of 'main' (argument count) must be of type 'int'
int main(MyClass myClass) {
^
1 error generated.

g++生成的main文件给出了SIGSEGV(为什么?

那么,如果可以定义 main 的实现,为什么clang给出错误g++而生成的文件给出SIGSEGV


我还更进一步并创建了一个不同的代码,以便能够将MyClass对象传递给main.c++,如下所示:

#include <iostream>
#include "main.h"
#include <unistd.h>

int main() {
MyClass myClass;
execve("./main",myClass,NULL);
return 0;
}

但是,由于execve将第二个参数作为char* const *,因此它不会编译。如何将 myClass 对象传递给g++生成的main文件?

命令

g++ -o main main.c++ -O3成功编译,但出现警告

这不是成功的编译。您应该始终使用-Werror.如果您未能这样做,然后决定忽略警告并继续运行程序,则由您自己负责。你最好完全清楚你在做什么。有关详细信息,请参阅此处。

G++生成的主文件给出了SIGSEGV(为什么?

编译器已警告您。倾听它符合您的最大利益。如果事情进展顺利,很可能是因为你忽略了警告。

为什么 clang 给出错误,而 g++ 生成的文件给出 SIGSEGV?

该程序不是有效的C++程序。警告和错误之间没有有意义的区别。

如何将 myClass 对象传递给 g++ 生成的主文件?

你不能。main必须具有等效于以下两个表单之一的表单:

int main()
int main(int argc, char* argv[])

(斜体可选(其他形式的main是实现定义的。这意味着您的实现需要以文档化的方式支持它们。除非您已阅读实现的文档并发现它支持所需的main形式,否则无法做到这一点。

除了有一个实现定义的main之外,程序能够获得类类型的对象的唯一方法是构造该对象。

你很接近。您已经确定了尝试作为参数传递给main()的主要问题 - 这不起作用。main()的声明由标准定义,您只能传递字符串值(以 nul 结尾的字符数组...C 字符串(作为参数。

在您的情况下,您需要在main()中创建类的实例,例如

#include <iostream>
#include "main.h"
int main() {
MyClass myClass;
std::cout << myClass.geti() << std::endl; 
return 0;
}

您的main.h标题在第 10 行存在可变阴影问题:

inline void seti(int i)  {

int i在第 3 行遮盖先前的声明,例如int i;(尽管后果不太可能重要(。只需将第二个声明中的变量名称替换为j(或任何您喜欢的内容(。您的代码将在没有警告的情况下编译,例如

class MyClass {
private:
int i;
public:
MyClass();
inline int geti() {
return i;
}
inline void seti(int j)  {
this->i = j;
}
~MyClass();
};
MyClass::MyClass() {
this->i = 2;
}
MyClass::~MyClass() {
}

示例使用/输出

$ ./bin/main
2

您还可以调用seti()函数来更新类中的私有变量,例如

myClass.seti(5);
std::cout << myClass.geti() << std::endl; 

现在将输出5.

如果您有其他问题,请告诉我。