【问题标题】:Can we find the caller in a member function in C++?我们可以在 C++ 的成员函数中找到调用者吗?
【发布时间】:2011-12-19 03:00:59
【问题描述】:

我有一个类,我们称它为 class myClass

class myClass{

  // some math operations
  myClass get_difference(myClass &b)
  {
       print_operation(*this, b);
       do_something else
       return...
  }
  myClass get_sum(myClass &b)

// pseudocode 
void print_operation(const myClass *a, const myClass &b)
{
     if function == get_sum
         print a << "plus" << b;
     if function == get_difference
         print a << "minus" << b;
}

  // overload cout as well
};

假设我调用了以下代码

myClass anObject(1,2);
myClass anotherObject(3,4);

anObject.get_sum(anotherObject);
anObject.get_difference(anotherObject);

get_sum / get_difference 将调用 print_operation,但我希望能够确定调用者以便使用不同的输出格式。

简单的方法:使用 switch-case 添加一个名为“id”的新参数。给每个函数(调用者)一个 id,并在 print_operation 中使用 switch-case 语句。

但是,还有其他选择吗?更优雅的解决方案?

谢谢。

【问题讨论】:

  • 更优雅 - 不。替代方案 - 模板。 Hack - 使用堆栈跟踪(取决于平台)。
  • 这不是一种天真的方法,而是 正确 方法:传入某种print_operation 可以用来做正确事情的参数。函数不应该知道,也不应该关心谁/什么调用了它们,只知道它们被调用并被赋予了这些参数。
  • 哈哈。谢谢。我不会知道的。总有人能想出更聪明的方法。但是,下面的建议非常有用。我接到你了。 :) 重要的是:“函数不应该知道,也不应该关心谁/什么调用了它们。”

标签: c++ function


【解决方案1】:

您是否考虑在调用者中添加virtual const std::string&amp; getFormatted() const

如果格式是运算符的两个参数的函数,则您必须创建某种组合表来查找格式。

如果格式只是每个参数的打印长度的函数(简单得多),您可以使用virtual size_t getFormatLength() const

注意:print_operation() 对调用者一无所知,除了它有一个 getFormatted() 函数外,调用者可以根据 op 的值格式化自己。

这是在工作的 OOP/多态性。

正如 Andrew Marshall 在上面的评论中回答的那样,OOP/封装的一部分是,您不应该对调用者的实现一无所知。

多态,做得对,应该尝试将实现细节封装在远离调用者的地方。

class myClass
{
  public:
    virtual std::string getFormatted( const std::string& op ) const = 0;
};

class A : public myClass
{
  public:
    virtual std::string getFormatted( const std::string& op ) const
    {
      // switch on the value of op or the length of op, etc...

      return std::string( "this, formatted according to class A specs and op" );
    }
};

class B : public myClass
{
  public:
    virtual std::string getFormatted( const std::string& op ) const
    {
      // switch on the value of op or the length of op, etc...

      return std::string( "this, formatted according to class B specs and op" );
    }
};

void print_operation(const myClass &a, const myClass &b )
{
  std::string op;

  if ( function == get_sum ) {
    op = "plus";
  } else if ( function == get_difference ) {
    op = "minus"; 
  }
  std::cout << a.getFormatted( op ) << op << b.getFormatted( op );
}

【讨论】:

  • 我不确定我是否理解 getFormat 的作用?介意扩展一下吗?谢谢!
  • @CppLearner 它使您的 myClass 的特定实例有机会指定格式应该是什么样的,因为实现将存在于 myClass 的子类中。当您说“但我希望能够确定调用者以便使用不同的输出格式”时,拥有虚拟 getFormat() 将使调用者有机会指定输出格式。
  • 谢谢kfmfe04 我想问你是否指的是继承和多边形。谢谢。真的很有帮助。
  • @CppLearner - 反馈意见 - 祝你在 C++ 中的冒险之旅好运!
【解决方案2】:

Cpp 函数不知道谁是调用者,除非你破解堆栈,这有点复杂。所以,一般来说,你必须将信息(函数参数、模板参数、数据成员..)传递给 print_operation 来告诉它要打印什么操作。

所以答案不是更优雅的解决方案。

【讨论】:

  • 嗨。感谢您的答复。是的。但在这个阶段,我会坚持使用简单的开关盒解决方案。用模板等重写我的课程现在一团糟:) 谢谢。
【解决方案3】:

我不认为问题归结为知道来电者是谁。听起来您确实想定义不同的方式来格式化数据,并且不同的调用者可能需要不同的格式化程序。

从 .NET 中吸取教训,您可能会考虑使用格式字符串来定义如何输出数据的设计,例如 IFormattable.ToString。在该示例中,格式字符串用于区分不同的输出格式。在您的情况下,您可以使用整数、枚举或任何合适的方式来定义它。

【讨论】:

  • 嗨。这是正确的。不同呼叫者的不同格式。我会调查的。谢谢。
猜你喜欢
  • 2010-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-04
  • 1970-01-01
  • 1970-01-01
  • 2011-05-22
相关资源
最近更新 更多