2014-01-14 4 views
4

Вот некоторые C++ код:Является ли этот код корректным?

#include <iostream> 

class A 
{ 
    int x; 
    int y; 
    double v; 

    public: 
     A(int x, int y) 
      :x(x),y(y) 
     { 
      std::cerr << "A("<<x<<","<<y<<")\n"; 
     } 
     ~A() 
     { 
      std::cerr << "~A()\n"; 
     } 
     operator double*() 
     { 
      v=1.5*x+y; 
      return &v; 
     } 
}; 

void f(double* val) 
{ 
    std::cerr << "f("<<*val<<")\n"; 
    *val=0.3; 
} 

int main() 
{ 
    f(A(3,5)); 
} 

я получаю следующее в качестве выходного сигнала:

A (3,5)
F (9,5)
~ А()

Т.е. как я хотел бы, чтобы он работал. Но я не уверен, должен ли деструктор Aпослеf возвращается. Гарантировано ли это? Может ли указатель, возвращаемый operator double*(), каким-то образом стать недействительным в вызове f?

ответ

3

Аргументы функции оцениваются до вызова функции, а временные данные будут жить до конца полного выражения, в котором они находятся. Таким образом, да, пример A будет жить до конца вызов f.

4

Вы объявляете объект A как фактический параметр f, когда вы это делаете, для всех эффектов новый объект похож на локальную переменную f, поэтому ~ A гарантированно вызывается в конце выполнения f.

Если f возвращает адрес, возвращаемый operator double*(), и он используется после возвращения f, вы получите доступ к недопустимой памяти. Один из способов избежать этой ситуации - сделать статичным, но вы должны учитывать, что в вашем коде объект, созданный классом класса A, выходит только во время работы f-блока.

Смежные вопросы