【问题标题】:Displaying object name inside destructor在析构函数中显示对象名称
【发布时间】:2012-12-22 02:21:04
【问题描述】:

FileTwo.h 内部

   #include"iostream"
    using namespace std ;
    class FileTwo{
    public:
      FileTwo(){
        cout<<"constructor for";//Here want to show the object for which the constructor has been called
      }
    ~Filetwo(){
      cout<<"Destructor for ";//Here want to show the object for which the destructor has been called 
    };

main.cpp 中

#include"Filetwo.h" 

int main(){
  FileTwo two ;
  return 0;
}

我知道这个示例程序非常小,所以我们可以找出调用了构造函数和析构函数的对象。但是对于大项目有没有办法知道对象名称?提前致谢。

【问题讨论】:

  • 你说的“名字”是什么意思?变量的标识符? foo(FileTwo()); 这样的代码中的“名称”是什么?
  • 你不能。 c++ 不支持反射。
  • @zapredelom 反射与它无关。对象在 C++ 中没有名称,句号。再多的反思也无法解决这个问题。另一方面,C++ 确实有 RTTI,它会提供类型信息。
  • @Angew::yes 标识符。在这种情况下是两个。

标签: c++ object constructor destructor


【解决方案1】:

除非您命名对象,否则这是不可能的。像这样的:

#include <iostream>
#include <string>
using namespace std;
class FileTwo {
  public:
    FileTwo(const std::string &myName) : name(myName){
      cout<<"constructor for" << name;//Here want to show the object for which the constructor has been called
    }
    ~Filetwo(){
      cout<<"Destructor for " << name;//Here want to show the object for which the destructor has been called 
    }

  private:
    std::string name;
};

然后把main改成:

#include"Filetwo.h" 
int main(){
  FileTwo two("two 11");
}

【讨论】:

    【解决方案2】:

    无法为对象命名,您所能做的就是创建一个私有变量来保存名称。

    using namespace std;
    class myClass
    {
        private:
        string className;
    
        public:
        ~myClass()
        {
            cout<<this->className;
        }
    };
    

    你可以为你的变量创建setter和getter。

    void SetName(string name)
    {
       this->className = name;
    }
    
    string GetName()
    {
       return this->className;
    }
    

    【讨论】:

      【解决方案3】:

      这是可能的。如果您的编译支持__PRETTY_FUNCTION____func__(参见this),那么您可以这样做:

      #include <iostream>
      using namespace std;
      class FileTwo{
        public:
          FileTwo(){
            cerr<<"constructor for "<< __PRETTY_FUNCTION__ <<" at "<<&(*this)<<endl;
          }
          ~FileTwo(){
            cerr<<"Destructor for "<< __PRETTY_FUNCTION__ <<" at "<<&(*this)<<endl;
          }
      };
      
      int main(){
        FileTwo two;
        return 0;
      }
      

      请注意,我还打印到cerr 以确保此输出立即刷新并且在程序崩溃时不会丢失。此外,由于每个对象都有一个唯一的 *this 指针,我们可以使用它来查看特定对象何时被制造或被杀死。

      上述程序在我电脑上的输出是:

      constructor for FileTwo::FileTwo() at 0x7fff641cde40
      Destructor for FileTwo::FileTwo() at 0x7fff641cde40
      

      请注意,__func__ 是 C99 标准标识符。 C++0x 以“实现定义的字符串”的形式增加了支持。

      __FUNCTION__ 是一些编译器支持的预标准扩展,包括 Visual C++(参见 documentation)和 gcc(参见 documentation)。

      __PRETTY_FUNCION__ 是一个 gcc 扩展,它做同样的事情,但更漂亮。

      This question 有关于这些标识符的更多信息。

      根据您的编译器,这可能会返回类的名称,尽管它可能有点混乱。

      #include <iostream>
      #include <typeinfo>
      
      using namespace std;
      class FileTwo{
        public:
          FileTwo(){
            cerr<<"constructor for "<< typeid(*this).name() <<" at "<<&(*this)<<endl;
          }
          ~FileTwo(){
            cerr<<"Destructor for "<< typeid(*this).name() <<" at "<<&(*this)<<endl;
          }
      };
      
      int main(){
        FileTwo two;
        return 0;
      }
      

      如果您试图获取实例化类的变量的名称(在您的情况下为two),那么据我所知,没有办法做到这一点。以下将模拟它:

      #include <iostream>
      #include <string>
      
      using namespace std;
      class FileTwo{
        public:
          FileTwo(const std::string &myName) : myName(myName) {
            cerr<<"constructor for "<< myName <<" at "<<&(*this)<<endl;
          }
          ~FileTwo(){
            cerr<<"Destructor for "<< myName <<" at "<<&(*this)<<endl;
          }
        private:
          std::string myName;
      };
      
      int main(){
        FileTwo two("two");
        return 0;
      }
      

      【讨论】:

      • @Learner,你的答案最终是什么?
      • 假设在我的一个函数中我想使用 _ FUNCTION_ 返回函数名,那么该怎么做呢?
      • @Richard::not yet get my answer 。仍在寻找它。在您的回答中,我可以找到函数名称。但它没有告诉我哪个对象正在调用该函数。我们可以得到那个对象的地址。但是有什么办法可以得到那个对象的名字吗?
      • @Learner, __PRETTY_FUNCTION__ 似乎是这样做的,在我的回答中您可以看到它打印“FileTwo::FileTwo()”,这是类的名称,后跟功能。这有帮助吗?
      • 是的。我从中得到了一些帮助。由于我们在 main 中声明了对象二,因此在我的 post 构造函数中被调用。我想在构造函数中显示这个名称。就像每当我们调用构造函数时,屏幕上都会显示两个。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-23
      • 1970-01-01
      • 1970-01-01
      • 2016-02-10
      • 2020-05-04
      相关资源
      最近更新 更多