C++ 请教如何获得一个类的实例化后的实例名?

imdjs 2017-01-09 04:49:22
我知道用typeid(var).name() 可以获得当然实例的类名,但如果我想获得当前实例名,有没有这种可能?
因为这个功能比较有用,例如我有很多个同一个类的不同实例,但其中某个实例出错了(如越界或其它问题),debug只会显示这个实例的类名.这样还是要花很多时间排查,如果我能立刻知道是哪个实例出错那么问题几乎立刻得到解决.
...全文
1081 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
imdjs 2017-01-11
  • 打赏
  • 举报
回复
用一个自定义vector当然可以测试 ,但这样,你写的代码就不能作为正常代码来用了.例如别人就不能编译了.而我现在是修改vector源码,但我的源码,只要去掉某个define就可以作为正常代码编译.加上define又可以作为测试用. 而且目前我已经完成了,并通过测试 .完全达到我的目的. 这是宏定义:

#ifdef __STL_TO_LIST__

    #define VECTOR(type,L)   vector<type>L(#L)
    #define MAP(type1,type2,D)   map<type1,type2>D(#D)
    #define SET_NAME(T)    T.setName(#T);

    //------------------------------
    #else
    #define VECTOR(type,V)   vector<type>V
    #define MAP(type1,type2,D)   map<type1,type2>D

#endif


#ifdef __STL_TO_LIST__
template<typename T>
inline void setNames(vector<vector<T>>&Vt__)
    {
    int iSize=Vt__.size();
    char*Vname=Vt__.getName();int iLen=strlen(Vname);
    if(Vname==NULL)
        {printf("!!!V没有name\n");return ;}
    for(int i=0;i<iSize;i++)
        {
        char cNUM[10], c_[10]="_";
        itoa(i,cNUM,10);strcat(c_,cNUM);//_0
        char*cNameToSet=merge(Vname,c_);//V_0
        Vt__[i].setName(cNameToSet);
        delete[]cNameToSet;
        }
    
    }
#endif

//========================================================
#ifdef __STL_TO_LIST__
    template<typename T>
    inline void RESIZE(int iSzie,vector<vector<T>>&Vt__)
        {
        Vt__.resize(iSzie);
        setNames(Vt__);
        }
    #else
    #define RESIZE(iSzie,Vt__)    Vt__.resize(iSzie)
#endif

//========================================================
#ifdef __STL_TO_LIST__
    template<typename T>
    inline void RESIZE2(int iSzie,vector<T>&Value,vector<vector<T>>&Vt__)
        {
        Vt__.resize(iSzie,Value);
        setNames(Vt__);
        }
    #else
    #define RESIZE2(iSzie,Value,Vt__)    Vt__.resize(iSzie,Value)
        
#endif

//========================================================
#ifdef __STL_TO_LIST__
    template<typename T>
    inline void ASSIGN(int iSzie,vector<T>&Value,vector<vector<T>>&Vt__)
        {
        Vt__.assign(iSzie,Value);
        setNames(Vt__);
        }
    #else
    #define ASSIGN(iSzie,Value,Vt__)    Vt__.assign(iSzie,Value)
#endif

这是测试 代码

#define __STL_TO_LIST__

void main()
    {

    VECTOR(vector<float>,VV测试) ;vector<float>Vf(2,3);
    //VV测试.setName("MY");SET_NAME(VV测试);//通过测试
    
    RESIZE2(5,Vf,VV测试);//通过测试
    RESIZE(3,VV测试);//通过测试
#ifdef __STL_TO_LIST__
    printf("typeid(VV测试)= %s○ name= %s\n",typeid(VV测试).name(),VV测试.getName());
    //VV测试.clear();VV测试=VV;//就算clear()或赋值,也不会修改名称
    printf("VV测试= %s\n",VV测试.getName());
    for(int i=0;i<4;i++)
        {
        printf("VV测试[i]= %s\n",VV测试[i].getName());//打印 vvd_0,vvd_1,vvd_2,vvd_3
        }


#endif

   }
还有内置vector的修改就不帖出来了.
zilaishuichina 2017-01-11
  • 打赏
  • 举报
回复
引用 11 楼 imdjs 的回复:
[quote=引用 10 楼 zilaishuichina 的回复:] [quote=引用 8 楼 imdjs 的回复:] [quote=引用 6 楼 zilaishuichina 的回复:] 既然能debug,那你就顺着堆栈往上找就可以了, 能确定到哪一行出错, 还不能确定哪个实例出错么
我是希望有一种更直观的方法,一出错立刻告诉我是那个变量出错在哪一行哪一层的嵌套,当然用传统方法也能找到问题出处但比较花时间.特别是在多个嵌套vector的时候.你很难立刻知道是哪一层越界了.[/quote] 那如果按照你的思路

	std::vector<int> arr1;
	std::vector<std::vector<int>> arr2;
	std::vector<std::vector<int>> arr3;
	std::vector<std::vector<std::vector<int>>> arr4;

	arr1.push_back(2);
	arr2.push_back(arr1);
	arr3.push_back(arr1);
	arr4.push_back(arr3);
对于arr2[0] , arr3[0], arr4[0][0] 你希望他们的实例名分别叫什么?[/quote] 按层级命名,arr2[0]叫 arr2_0 arr3[0]叫 arr3_0 arr4[0][0] 叫 arr4_0_0 arr4[1][2] 叫 arr4_1_2 因为我现在主要处理大场景的3d数据,所以通常会有4到5个vector 嵌套,所以这样命名比较直观.[/quote] 那就简单了: 直接继承vector就好了, 跟是否debug/release 也没有关系了, 之前vector的接口该怎么用还怎么用, 那些不需要进行这种检测的实例,也不受影响 MyVector.h

#ifndef __MyVector_h__
#define __MyVector_h__

#include <vector>

template <class T>
class MyVector;

template <class T>
bool IsMyVector(MyVector<T>& v, const std::string& fatherName, size_t _Pos)
{
	v.SetName(fatherName, _Pos);
	return true;
}

template <class T>
bool IsMyVector(T& v, const std::string& fatherName, size_t _Pos)
{
	return false;
}

template <class T>
class MyVector : public std::vector<T, std::allocator<T>>
{
public:
	MyVector(const std::string& name) : m_Name(name)
	{

	}

	void SetName(const std::string& fatherName, size_t _Pos)
	{
		char name[1024] = {};
		sprintf_s(name, 1024, "%s_%d", fatherName.c_str(), _Pos);
		m_Name = name;
	}

	T& operator[](size_t _Pos)
	{
		if (_Pos < size())
		{
			T& t = (*(this->_Myfirst + _Pos));
			IsMyVector(t, m_Name, _Pos);
			return t;
		}
		else
		{
			char name[1024] = {};
			sprintf_s(name, 1024, "%s_%d", m_Name.c_str(), _Pos);
			m_Name = name;

			throw m_Name;
		}
	}

private:
	std::string m_Name;
};

#endif
测试代码:

#include <iostream>

#include "MyVector.h"

int main(int argc, char* argv[])
{
	MyVector<int> arr1("arr1");
	MyVector<MyVector<int>> arr2("arr2");
	MyVector<MyVector<MyVector<int>>> arr3("arr3");
	MyVector<MyVector<MyVector<MyVector<int>>>> arr4("arr4");

	arr1.push_back(2);
	arr2.push_back(arr1);
	arr3.push_back(arr2);
	arr4.push_back(arr3);

	try
	{
		arr4[0][0][0][10] = 2;
	}
	catch (std::string& e)
	{
		std::cout << "exception:" << e.c_str() << std::endl;
	}

	try
	{
		MyVector<MyVector<int>>& temp = arr4[0][0];
		temp[10][0] = 2;
	}
	catch (std::string& e)
	{
		std::cout << "exception:" << e.c_str() << std::endl;
	}

	try
	{
		MyVector<MyVector<MyVector<MyVector<int>>>>::iterator it = arr4.begin();
		MyVector<MyVector<MyVector<int>>>& temp = *it;
		temp[10][0][0] = 2;
	}
	catch (std::string& e)
	{
		std::cout << "exception:" << e.c_str() << std::endl;
	}

	system("pause");

	return 0;
}
把你需要检测的vector 换成 MyVector 就好了 输出: exception:arr4_0_0_0_10 exception:arr4_0_0_10 exception:arr4_0_10
imdjs 2017-01-10
  • 打赏
  • 举报
回复
引用 10 楼 zilaishuichina 的回复:
[quote=引用 8 楼 imdjs 的回复:] [quote=引用 6 楼 zilaishuichina 的回复:] 既然能debug,那你就顺着堆栈往上找就可以了, 能确定到哪一行出错, 还不能确定哪个实例出错么
我是希望有一种更直观的方法,一出错立刻告诉我是那个变量出错在哪一行哪一层的嵌套,当然用传统方法也能找到问题出处但比较花时间.特别是在多个嵌套vector的时候.你很难立刻知道是哪一层越界了.[/quote] 那如果按照你的思路

	std::vector<int> arr1;
	std::vector<std::vector<int>> arr2;
	std::vector<std::vector<int>> arr3;
	std::vector<std::vector<std::vector<int>>> arr4;

	arr1.push_back(2);
	arr2.push_back(arr1);
	arr3.push_back(arr1);
	arr4.push_back(arr3);
对于arr2[0] , arr3[0], arr4[0][0] 你希望他们的实例名分别叫什么?[/quote] 按层级命名,arr2[0]叫 arr2_0 arr3[0]叫 arr3_0 arr4[0][0] 叫 arr4_0_0 arr4[1][2] 叫 arr4_1_2 因为我现在主要处理大场景的3d数据,所以通常会有4到5个vector 嵌套,所以这样命名比较直观.
zilaishuichina 2017-01-10
  • 打赏
  • 举报
回复
引用 8 楼 imdjs 的回复:
[quote=引用 6 楼 zilaishuichina 的回复:] 既然能debug,那你就顺着堆栈往上找就可以了, 能确定到哪一行出错, 还不能确定哪个实例出错么
我是希望有一种更直观的方法,一出错立刻告诉我是那个变量出错在哪一行哪一层的嵌套,当然用传统方法也能找到问题出处但比较花时间.特别是在多个嵌套vector的时候.你很难立刻知道是哪一层越界了.[/quote] 那如果按照你的思路

	std::vector<int> arr1;
	std::vector<std::vector<int>> arr2;
	std::vector<std::vector<int>> arr3;
	std::vector<std::vector<std::vector<int>>> arr4;

	arr1.push_back(2);
	arr2.push_back(arr1);
	arr3.push_back(arr1);
	arr4.push_back(arr3);
对于arr2[0] , arr3[0], arr4[0][0] 你希望他们的实例名分别叫什么?
AlbertS 2017-01-10
  • 打赏
  • 举报
回复
引用 7 楼 imdjs 的回复:
我决定要修改vector 的源码,增加 char*name 成员,然后增加 vector(char*c) 的构造函数,增加 get_name() 与 set_name() 成员函数 用宏初始化实现 #ifdef __STL_TO_LIST__ #define VECTOR_STR(type,L) vector<type>L(#L) #define VECTOR(type) vector<type> #define MAP_STR(type1,type2,D) map<type1,type2>D(#D) #define MAP(type1,type2) map<type1,type2> #define SET_NAME(T) T.set_name(#T) #endif 并在vector 越界检测里增加 打印信息可以打印自身的成员变量 name 当然这些是在debug模式下.
自己动手,丰衣足食
imdjs 2017-01-10
  • 打赏
  • 举报
回复
引用 6 楼 zilaishuichina 的回复:
既然能debug,那你就顺着堆栈往上找就可以了, 能确定到哪一行出错, 还不能确定哪个实例出错么
我是希望有一种更直观的方法,一出错立刻告诉我是那个变量出错在哪一行哪一层的嵌套,当然用传统方法也能找到问题出处但比较花时间.特别是在多个嵌套vector的时候.你很难立刻知道是哪一层越界了.
imdjs 2017-01-10
  • 打赏
  • 举报
回复
我决定要修改vector 的源码,增加 char*name 成员,然后增加 vector(char*c) 的构造函数,增加 get_name() 与 set_name() 成员函数 用宏初始化实现 #ifdef __STL_TO_LIST__ #define VECTOR_STR(type,L) vector<type>L(#L) #define VECTOR(type) vector<type> #define MAP_STR(type1,type2,D) map<type1,type2>D(#D) #define MAP(type1,type2) map<type1,type2> #define SET_NAME(T) T.set_name(#T) #endif 并在vector 越界检测里增加 打印信息可以打印自身的成员变量 name 当然这些是在debug模式下.
zilaishuichina 2017-01-10
  • 打赏
  • 举报
回复
既然能debug,那你就顺着堆栈往上找就可以了, 能确定到哪一行出错, 还不能确定哪个实例出错么
小竹浮生 2017-01-10
  • 打赏
  • 举报
回复
引用 4 楼 shihengzhen101 的回复:
[quote=引用 2 楼 imdjs 的回复:] [quote=引用 1 楼 shihengzhen101 的回复:] C++没有反射,但是想要获得实例名很简单啊,你在类中加入一个字段name,创建的时候设置为不同的值,debug的时候打印name变量不就行了?
这个也是个方法,但有点麻烦,而且无法对STL 库的类实例这样做.[/quote] 这个只能你自己去标记了[/quote] 可以看看宏定义,__file__,__function__,__line__
AlbertS 2017-01-10
  • 打赏
  • 举报
回复
引用 2 楼 imdjs 的回复:
[quote=引用 1 楼 shihengzhen101 的回复:] C++没有反射,但是想要获得实例名很简单啊,你在类中加入一个字段name,创建的时候设置为不同的值,debug的时候打印name变量不就行了?
这个也是个方法,但有点麻烦,而且无法对STL 库的类实例这样做.[/quote] 这个只能你自己去标记了
ID870177103 2017-01-10
  • 打赏
  • 举报
回复
c++没有实例名,就算是java也没有 你需要的话只能自己保存 使用宏声明变量的话,可以用#让编译器保存变量名
imdjs 2017-01-09
  • 打赏
  • 举报
回复
引用 1 楼 shihengzhen101 的回复:
C++没有反射,但是想要获得实例名很简单啊,你在类中加入一个字段name,创建的时候设置为不同的值,debug的时候打印name变量不就行了?
这个也是个方法,但有点麻烦,而且无法对STL 库的类实例这样做.
AlbertS 2017-01-09
  • 打赏
  • 举报
回复
C++没有反射,但是想要获得实例名很简单啊,你在类中加入一个字段name,创建的时候设置为不同的值,debug的时候打印name变量不就行了?

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧