引数を内部で判断する方法

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
純夏

引数を内部で判断する方法

#1

投稿記事 by 純夏 » 4年前

class A{
void func( A* a ){
if( new の場合 )
else
};
}

int main(){
A a;
a.func( new A() );
A b;
a.func( &b );
}

class Aのfunc内で 、
・new A() の場合
・&Aの場合
で処理を分けたいのですが、可能でしょうか?

Rittai_3D
記事: 525
登録日時: 7年前

Re: 引数を内部で判断する方法

#2

投稿記事 by Rittai_3D » 4年前

コードを張る場合はcodeタグを使用してください。

オーバーロードを使用すれば良いのではないのでしょうか。

コード:

#include <iostream>

using namespace std;

class A
{
public:

    A() = default;
    ~A() = default;
    
public:
    
    void func( A* a )
    {
        ( void )a;
        cout << "prm : pointer" << endl;
        
        delete a;
        a = nullptr;
    }
    
    void func( A& a )
    {
        ( void )a;
        cout << "prm : reference" << endl;
    }
};

int main()
{
    A a;
    a.func( new A );
    
    A b;
    a.func( b ); // この間違い・・・?
}

実行結果
初心者です

アバター
みけCAT
記事: 6274
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: 引数を内部で判断する方法

#3

投稿記事 by みけCAT » 4年前

非常に難しい(多分無理)だと思います。

とりあえず、Wandboxで動いた環境依存であり、本当に動く保証もないコードを貼ります。

コード:

#include <cstdio>

class A{
    public:
        void func( A* a ){
            printf("0x%llx\n",(long long)a);
            if( 0x700000LL < (long long)a && (long long)a < 0x700000000000LL )
                puts("new A()");
            else
                puts("&A");
        }
};

A z;
int main(){
    static A y;
    A a;
    a.func( new A() );
    A b;
    a.func( &b );
    a.func( &y );
    a.func( &z );
    A *c = new A();
    a.func( &*c ); // これはどっちが正解?
    return 0;
}
http://melpon.org/wandbox/permlink/htlzW1ZVhf6nxwDj

Ideone.com版

コード:

#include <cstdio>

class A{
    public:
        void func( A* a ){
            printf("0x%llx\n",(long long)a);
            if( 0x8050000LL < (long long)a && (long long)a < 0xf000000000000000LL )
                puts("new A()");
            else
                puts("&A");
        }
};

A z;
int main(){
    static A y;
    A a;
    a.func( new A() );
    A b;
    a.func( &b );
    a.func( &y );
    a.func( &z );
    A *c = new A();
    a.func( &*c ); // これはどっちが正解?
    return 0;
}
https://ideone.com/GZ9I45
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6274
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: 引数を内部で判断する方法

#4

投稿記事 by みけCAT » 4年前

純夏 さんが書きました: class Aのfunc内で 、
・new A() の場合
・&Aの場合
で処理を分けたいのですが、可能でしょうか?
どうしてそんな変なことがしたいのですか?

もしかして:The XY Problem
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
tk-xleader
記事: 153
登録日時: 9年前
連絡を取る:

Re: 引数を内部で判断する方法

#5

投稿記事 by tk-xleader » 4年前

 new Aと&bの結果の型はどちらもA*ですから、これらは型としては区別できません。

 ただし、トリッキーで汚い方法であれば、マクロと文字列処理を利用すれば出来るかもしれないですね。下のコードは未検証ですが、引数に文字列を乗せてその文字列を整理して分類するという考え方自体は示せていると思います。

コード:

#include<cctype>
#include<string>
#include<algorithm>
#define func(ARG) func_impl(ARG,#ARG)
//本来ならstd::isspaceを直接remove_ifに渡せるはずなんですが…
struct IsSpaceObject{
	bool operator()(int c)const{
		return std::isspace(c);
	}
};

class A{
	// ↓関数名をfunc_implに変更する(呼び出し側はfuncで呼び出す)。
	void func_impl( A* a , std::string arg_style){
		arg_style.erase(std::remove_if(arg_style.begin(),arg_style.end(),IsSpaceObject()),arg_style.end());
		if(arg_style == "newA"){
			/*newで作成され、直接そのオブジェクトのアドレスが引数として渡された場合の処理*/
		}else{
			/*上記以外の場合*/
		}
	}
};
追記:
オフトピック
よくよく考えてみると、std::isspaceが直接remove_ifに渡せないのは、<cctype>と<locale>の両ヘッダでisspaceがオーバーロードされているからですね。

hoge

Re: 引数を内部で判断する方法

#6

投稿記事 by hoge » 4年前

強引に判断させてみた

コード:

#include <iostream>
#include <new>
#include <set>

using namespace std;
 
class A
{
public:
 
    A() = default;
    ~A() = default;
    void* operator new(size_t s)
    { void*p = ::operator new(s); new_.insert(p); return p; }
    
public:
    
    void func( A* a )
    {
        if(new_.find(static_cast<void*>(a)) != new_.end())
          cout << "new" << endl;
        else
          cout << "not new" << endl;
    }

private:
    static set<void*> new_;
};
set<void*> A::new_;

int main()
{
    A a;
    a.func( new A );
    
    A b;
    a.func( &b );
}

閉鎖

“C言語何でも質問掲示板” へ戻る