2012-04-11 14 views
1

Ich habe mich gefragt, ob es einen Weg gibt zu wissen, ob eine Funktion von einer anderen spezifischen Funktion aufgerufen wurde.Wie kann ich wissen, ob eine Funktion von einer bestimmten Funktion aufgerufen wurde? C++

doc(){ 
foo(); 
} 

bar() { 
doc(); 
} 

foo() { 
if (bar in the callStack) { /* do this */} 
} 

Danke !!

+0

Nein, es gibt keine Möglichkeit, dass in Standard C++ zu tun ist. –

+0

Nein, nicht portabel. – ildjarn

+2

Klassisches [XY-Problem] (http://meta.stackexchange.com/a/66378/147331)! Was versuchst du eigentlich? – Johnsyweb

Antwort

2

Sie können das nicht tun, ohne viele plattformspezifische Hacks zu verwenden. Ein Debugger gibt Ihnen diese Informationen, aber im Allgemeinen können Sie nicht auf den Stack zugreifen, ohne ASM-Hacker in C++ zu verwenden.

Wenn Sie das tun müssen, machen Sie etwas falsch mit Ihrem Design. Was versuchst du, damit wir helfen können?

+1

Sollte das nicht ein Kommentar sein, anstatt eine Antwort? Im Grunde sagen Sie, Sie können es tun, nur nicht portabel ... aber geben Sie kein Beispiel, wie es auf einer bestimmten Plattform (oder Zeigern dazu) getan werden könnte. – 0xC0000022L

+1

Nein, meine Antwort lautet: Tu es nicht.Manchmal ist die richtige Antwort nicht unbedingt die Antwort, nach der Sie suchen. Wenn er das fragen muss, wird die ASM-Zauberei, um das durchzuziehen, sowieso weit hinter ihm sein. –

+0

OK, fair genug – 0xC0000022L

2

Nicht, dass es eine gute Idee oder ein gutes Design ist, aber natürlich können Sie eine weitere globale Flag verwenden, wie:

doc(){ 
    foo(); 
} 

int inBar = 0; 

bar() { 
    inBar = 1; 
    doc(); 
    inBar = 0; 
} 

foo() { 
if (inBar) { /* do this */} 
} 
+1

Ya, und beachten Sie, dass Sie wahrscheinlich inBar statisch machen sollten, und auch, dass dies weder Thread noch instance-safe ist, wenn die Funktionen, nach denen er fragt, tatsächlich Methoden einer Klasse sind. –

+1

@Kevin: Du solltest das einfach nicht machen. –

+0

@Ed S. - Oh Hölle nein. Ich stimme völlig zu, dass dies schrecklich ist, aber ich kann auch sehen, dass Sie manchmal stark durch das, was Sie arbeiten, und/oder Deadlines eingeschränkt sind, und deshalb ist es wichtiger als alles andere, "die Tür zu öffnen". Ich hasse es, es zu tun, aber ich habe es, und ich bin mir sicher, dass jeder andere Entwickler auf dieser Seite auch einmal oder so etwas hat. –

0

können Sie bar ändern() eine globale Bool auf true Eintrag zu setzen und falsch am Ausgang. Testen der Bool in foo() wird Ihnen sagen, wenn Sie in der bar() Aufrufstack.

namespace { 
    bool test_bar = false; 

} 

void bar() { 
    test_bar = true; 

    // do stuff 


    test_bar = false; 
} 

Wenn Sie die oben müssen in einer multi_threaded Umgebung zu arbeiten, dann ist die globale Bool wird müssen lokale Thread (mit so etwas wie boost :: thread_specific_ptr) Diese Art von Konstrukt sollte nur für die Verfolgung Rennen verwendet werden Bedingungen, die in einem Debugger schwer zu finden sind, ist ein schnelles und schmutziges Werkzeug, andere Verwendungen weisen auf ein schlechtes Design hin.

2

Sie sollten eine Bibliothek verwenden, die zu Ihrem Compiler passt.

Für GCC können Sie an Backtraces denken. Dieser basiert auf GCC-Builtins c/c++: call stack v.2.

für Visual C hörte ich von StackWalk64, aber es selbst nie benutzt.

Sie können natürlich auch Ihre eigenen "Spuren" machen, aber ich denke, dass es nicht das ist, was Sie wollen.

0

, wie wissen, ob eine Funktion von einer bestimmten Funktion C++

Sie nicht das tun können genannt wurde. Sie können jedoch der Funktion

ein boolesches Argument hinzufügen und dieses Flag von bar setzen. Dies wird jedoch ein weiteres Problem verursachen - nichts wird andere Funktionen daran hindern, das Flag zu setzen.

Ich denke, das (zusätzliche Problem) kann auf diese Weise festgelegt werden:

class BarFlag{ 
private: 
    bool flag; 
protected: 
    friend void doc(); 
    BarFlag(bool flag_) 
    :flag(flag_){ 
    } 
public: 
    inline operator bool() const{ 
     return flag; 
    } 
    BarFlag() 
    :flag(false){ 
    } 
} 

void foo(BarFlag flag = BarFlag()){ 
    if (flag){/*do it*/}   
} 

//somewhere else 
void doc(){ 
    foo(BarFlag(true)); 
}