0

这个问题是关于函数堆栈创建的。

假设我们创建一个函数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)还创建其函数堆栈并创建局部变量ac.

2)现在假设我们通过引用调用:我的函数是fn(int* a,char* b)or并且分别fn(int& a, char& b)从我们的 main 调用,在这种情况下,还将创建一个带有返回地址、SP 等的函数堆栈。我的问题是,是否会有一个本地指针在这种情况下,或在堆栈上创建引用(即创建指向传递对象的指针或引用的本地副本)。还是没有创建对象的本地副本,而是直接传递了指针或引用指向的原始对象?fn(&A,&B)fn(A,B)

3)我们可以重载像fn(int& a,char& b)and这样的函数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
4

2 回答 2

4

构造函数是否myClass(int a,char c)还创建其函数堆栈并创建局部变量ac

是的,创建了一个函数堆栈,但ac不是函数堆栈的局部变量,它们是成员变量,并且生命周期不会随着构造函数的结束而结束。它们在它们所属的类实例的整个生命周期内保持活动状态。

还是没有创建对象的本地副本,而是直接传递了指针或引用指向的原始对象?

这称为通过引用传递。两种方式是:

  • 传递对象的地址或
  • 通过引用传递对象

在任何一种情况下,都不会创建对象的副本。实际对象可以在函数内修改,如果函数中1的指针指向被传递对象的地址,而2引用参数只是被传递对象的别名。

我们可以重载像fn(int& a,char& b)and这样的函数fn(int a,int b)吗?

不,您不能,因为编译器无法理解您在调用它时打算调用哪个函数版本:

int i = 10;
int j = 20;
fn(i,j);

我误读了, asfn(int& a,int& b)fn(int a,int b)而不是fn(int& a,char& b)and fn(int a,int b)
当然可以。它们具有不同的类型,因此有资格作为有效的重载函数。

于 2013-05-06T04:24:19.137 回答
0

首先,您的概念有点不正确。

即堆栈不是通过函数调用创建的。相反,每个执行线程都有自己的堆栈。它甚至在调用单个 main 时也存在。然而,当一个函数被调用时,一条 ACTIVATION 记录被压入堆栈。从函数返回时也会弹出相同的内容。

因此对于

  1. 堆栈已经存在,并且每次函数调用都会在堆栈上推送一条激活记录。变量在对象的整个生命周期中都存在。

  2. 如果您的函数将指针作为参数(即通过引用调用),则会有一个指针变量被压入堆栈,该变量被传递原始变量的地址。原始变量保持不变,通过指针修改其值将更改原始变量。

  3. 只有当它们的签名不同时,您才能重载函数。这意味着参数的类型、数量或顺序。在您引用的示例中,无法区分传递的 int 是变量还是变量的地址。因此,此重载将不起作用。

编辑:上面的第 3 点有轻微的错误。有问题引用的例如第二个参数不同,因此有资格作为有效重载。请注意,标准不仅仅是数据类型的名称(即 int 与 int * 也是不同的类型),而是给定输入值的事实,编译器应该能够区分并选择要调用的重载版本。

于 2013-05-06T04:24:42.437 回答