这个问题与功能堆栈创建有关。
假设我们创建一个函数fn(int a,char b)
并从main fn(A,B)
调用,在这种情况下,当函数被称为fn时。使用返回地址,堆栈指针(等)创建堆栈,其中创建局部变量和参数,并在返回时销毁。
我有几个问题: 1)对于我们的参数化构造函数假设
myClass{
int a;
char c;
public:
myClass(int a,char c)
{
this->a=a;
this->c=c;
}
};
构造函数myClass(int a,char c)
是否也创建了它的函数堆栈并创建局部变量a
和c
。
2)现在假设我们通过引用进行调用:我的函数是fn(int* a,char* b)
或fn(int& a, char& b)
并分别通过fn(&A,&B)
和fn(A,B)
从我们的主函数调用,在这种情况下也是,将使用返回地址,SP等创建函数堆栈。我的问题是,在这种情况下,是否会在堆栈上创建本地指针或引用(即创建指向传递对象的指针或引用的本地副本) 。或者是否没有创建对象的本地副本,并且指针或refence指向的原始对象是直接传递的?
3)我们可以重载fn(int& a,char& b)
和fn(int a,int b)
等函数吗?
谢谢
修改
#include <iostream>
using namespace std;
void fn(int , char);
//void fn (int* a, char* c);
void fn (int& a, char& c);
int main()
{
int a=10;
char c= 'c';
cout << "Inside main()" << endl;
cout << hex << "&a : " << &a << endl;
cout << hex << "&c : " << (int *)&c << endl;
fn(a,c);
//fn(&a,&c);
fn(a,c);
return 0;
}
void fn (int a, char c)
{
int tempInt;
char tempChar;
cout << "\n\nInside Call By Value Function " << endl;
cout << hex << "&a : " << &a << endl;
cout << hex << "&c : " << (int *)&c << endl;
cout << hex << "&tempInt : " << &tempInt << endl;
cout << hex << "&tempChar : " << (int *)&tempChar << endl;
}
/*void fn (int* a, char* c)
{
cout << "\n\nInside Call By Pointer Function " << endl;
cout << hex << "*a : " << a << endl;
cout << hex << "*c : " << (int*) c << endl;
}
*/
void fn (int& a, char& c)
{
cout << "\n\nInside Call By Reference Function " << endl;
cout << hex << "*a : " << &a << endl;
cout << hex << "*c : " << (int*) &c << endl;
}
输出:
$ make
g++ -Wall Trial.cpp -o Trial
Trial.cpp: In function `int main()':
Trial.cpp:19: error: call of overloaded `fn(int&, char&)' is ambiguous
Trial.cpp:5: note: candidates are: void fn(int, char)
Trial.cpp:7: note: void fn(int&, char&)
Trial.cpp:21: error: call of overloaded `fn(int&, char&)' is ambiguous
Trial.cpp:5: note: candidates are: void fn(int, char)
Trial.cpp:7: note: void fn(int&, char&)
make: *** [Trial] Error 1
答案 0 :(得分:4)
构造函数
myClass(int a,char c)
是否也创建其函数堆栈并创建局部变量a
和c
是的,创建了一个函数堆栈,但a
和c
不是函数堆栈的局部变量,它们是成员变量,生命周期不会以构造函数的结尾结束。它们在类实例的整个生命周期中都是活着的。
或者是否没有创建对象的本地副本,并且指针或引用指向的原始对象是直接传递的?
这被称为通过引用传递。这两种方式是:
在任何一种情况下,都不会创建对象的副本。可以在函数内修改实际对象。如果1
函数中的指针指向正在传递的对象的地址,而在2
的情况下,引用参数仅仅是对象的别名过去了。
我们可以重载像
fn(int& a,char& b)
和fn(int a,int b)
这样的函数吗?
不可以,因为编译器无法理解您在调用时打算调用哪个函数版本:
int i = 10;
int j = 20;
fn(i,j);
击> <击> 撞击>
我误读为fn(int& a,int& b)
和fn(int a,int b)
而不是fn(int& a,char& b)
和fn(int a,int b)
。
当然可以。它们具有不同的类型,因此有资格成为有效的重载函数。
答案 1 :(得分:0)
首先,您的概念略有不正确。
即。堆栈不是通过函数调用创建的。而是每个执行线程都有自己的堆栈。当调用一个主要时,它甚至就在那里。但是,在调用函数时,会在堆栈上推送ACTIVATION记录。从函数返回时会弹出相同的内容。
所以
堆栈已存在,并且每个函数调用都会在堆栈上推送激活记录。变量在对象的整个生命周期中都存在。
如果你的函数将一个指针作为参数(即通过引用调用),则会在堆栈上推送一个指针变量,该变量将传递给原始变量的地址。原始变量保持不变,通过指针修改其值将改变原始变量。
您只能在签名不同时重载功能。这意味着参数的类型,数量或顺序。在例如你引用过,不可能区分传递的int是变量还是变量的地址。因此,这种重载不起作用。
编辑:上面的第3点有轻微的错误。例如引用的问题有第二个参数不同,因此有资格作为有效过载。请注意,条件不仅仅是数据类型的名称(即int与int *也是不同的类型),而是给定输入值的事实,编译器应该能够区分并选择要调用的重载版本。 / p>