0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

多重継承すると後ろ側のクラスで分岐が発生する?

Posted at
Hage.hpp
#ifndef __HAGE_HPP__
#define __HAGE_HPP__

class NotifierA
{
public:
	virtual void notifyA() = 0;

};
class NotifierBC
{
public:
	virtual bool notifyB() = 0;
	virtual bool notifyC() = 0;

};
class Starter
{
public:
	void start1(NotifierA* n)
	{
		n->notifyA();
	}
	void start2(NotifierBC* n)
	{
		n->notifyB();
	}
};
#endif
Hoge.hpp
#ifndef __HOGE_HPP__
#define __HOGE_HPP__

#include "Hage/Hage.hpp"


class NotifierABC: public NotifierA, public NotifierBC
{
public:
	void notifyA(){}
	bool notifyB(){return true;}
	bool notifyC(){return true;}
};


class Hoge
{
public:
	Hoge():s_(),n_(){}
	void test1();
private:
	Starter s_;
	NotifierABC n_;
};
#endif
Hoge.cpp
#include "Hage/Hage.hpp"
#include "Hoge/Hoge.hpp"

void Hoge::test1()
{
	s_.start1(&n_);
	s_.start2(&n_);
	
	NotifierABC* n = new NotifierABC();
	s_.start1(n);
	s_.start2(n);
	delete n;
}
HogeTest.cpp

#include <CppUTest/TestHarness.h>

#include "Hage/Hage.hpp"
#include "Hoge/Hoge.hpp"

TEST_GROUP(FirstTestGroup)
{
};

TEST(FirstTestGroup, FirstTest)
{
	Hoge h;
	h.test1();
}
Makefile
.PHONY: all rebuild test cov clean
.SUFFIXES: .c .cpp .o

SRC:=$(shell find src/Hoge test/Hoge -name *.cpp)
OBJDIR:=test/Hoge/Obj
OBJ:=$(addprefix $(OBJDIR)/,$(subst /Hoge/,/,$(SRC:%.cpp=%.o)))
TARGET:=$(OBJDIR)/test.exe
CXXFLAGS:= --coverage -fprofile-arcs -ftest-coverage -I. -Iinclude -I/usr/local/include -g -O0 -fno-elide-constructors  -fno-inline -fno-inline-small-functions -fno-default-inline -fno-threadsafe-statics -fno-exceptions -L/usr/local/lib
#CXXFLAGS:=-coverage -I. -Iinclude -I/usr/local/include -O0 -fno-inline -fno-inline-small-functions -fno-default-inline -L/usr/local/lib -lCppUTest -lCppUTestExt
LCOV_FLAGS:=--rc lcov_branch_coverage=1
LCOVFILE:=$(OBJDIR)/lcov.info

all:$(TARGET)

rebuild:clean all

test:$(TARGET)
	./$(TARGET)

$(TARGET):$(OBJ)
	$(CXX) $(CXXFLAGS) -o $@  -Wl,--whole-archive $^ -Wl,--no-whole-archive -lCppUTest -lCppUTestExt

#$(OBJ): $(SRC)
#	$(CXX) $(CXXFLAGS) -c $< $(OUTPUT_OPTION)


test/Hoge/Obj/src/%.o:src/Hoge/%.cpp
	-mkdir -p test/Hoge/Obj/src/
	$(CXX) $(CXXFLAGS) -o $(@:%.o=%.s) -S $^
	$(CXX) $(CXXFLAGS) -o $@ -c $^

test/Hoge/Obj/test/%.o:test/Hoge/%.cpp
	-mkdir -p test/Hoge/Obj/test/
	$(CXX) $(CXXFLAGS) -o $(@:%.o=%.s) -S $^
	$(CXX) $(CXXFLAGS) -o $@ -c $^

cov:
	lcov $(LCOV_FLAGS) -c -d . -o $(LCOVFILE)
#	lcov $(LCOV_FLAGS) -e $(LCOVFILE) "*src/Hoge*" -o $(LCOVFILE)
	genhtml $(LCOV_FLAGS) --legend -o $(OBJDIR)/html $(LCOVFILE)

clean:
	-find . \( -name "*.o" -or -name "*.gcno" -or -name "*.gcda" -or -name "*.s" \) -exec rm {} \;
	-rm -f $(TARGET) $(LCOVFILE)

#ソースコードとアセンブラの対比が見たい場合
dump:
	objdump -d -S test/Hoge/Obj/test.exe>dmp.txt


こんなコードでmake test covするとHoge.cppのカバレッジの結果が以下のようになる。

A.PNG

次にHoge.hppのNotifierABCの継承の順番を入れ替えてカバレッジ取得してみる。

Hoge.hpp(partial)
class NotifierABC: public NotifierBC, public NotifierA
{
public:
	void notifyA(){}
	bool notifyB(){return true;}
	bool notifyC(){return true;}
};

B.PNG

以下の条件の場合に分岐が発生する?

  1. 多重継承しているクラスのインスタンスを関数の引数に渡す
  2. 関数の引数として扱うことができるクラスを先頭で継承していない
  3. インスタンスは動的に生成されたものである
start1部分のアセンブリコード
	s_.start1(n);
   10040118a:	48 83 7d a8 00       	cmpq   $0x0,-0x58(%rbp)
   10040118f:	74 1c                	je     1004011ad <_ZN4Hoge5test1Ev+0xcd>
   100401191:	48 8b 45 a8          	mov    -0x58(%rbp),%rax
   100401195:	48 8d 50 08          	lea    0x8(%rax),%rdx
   100401199:	48 8b 05 80 fe 01 00 	mov    0x1fe80(%rip),%rax        # 100421020 <__bss_start__+0x20>
   1004011a0:	48 83 c0 01          	add    $0x1,%rax
   1004011a4:	48 89 05 75 fe 01 00 	mov    %rax,0x1fe75(%rip)        # 100421020 <__bss_start__+0x20>
   1004011ab:	eb 17                	jmp    1004011c4 <_ZN4Hoge5test1Ev+0xe4>
   1004011ad:	ba 00 00 00 00       	mov    $0x0,%edx
   1004011b2:	48 8b 05 6f fe 01 00 	mov    0x1fe6f(%rip),%rax        # 100421028 <__bss_start__+0x28>
   1004011b9:	48 83 c0 01          	add    $0x1,%rax
   1004011bd:	48 89 05 64 fe 01 00 	mov    %rax,0x1fe64(%rip)        # 100421028 <__bss_start__+0x28>
   1004011c4:	48 8b 45 d0          	mov    -0x30(%rbp),%rax
   1004011c8:	48 89 c1             	mov    %rax,%rcx
   1004011cb:	e8 30 14 01 00       	callq  100412600 <_ZN7Starter6start1EP9NotifierA>
   1004011d0:	48 8b 05 59 fe 01 00 	mov    0x1fe59(%rip),%rax        # 100421030 <__bss_start__+0x30>
   1004011d7:	48 83 c0 01          	add    $0x1,%rax
   1004011db:	48 89 05 4e fe 01 00 	mov    %rax,0x1fe4e(%rip)        # 100421030 <__bss_start__+0x30>

なんかjeしてる。
je成立しなかったらアドレスを8進めているみたいなので、先頭の継承元でだめだったら次の継承元っていう処理だろうか。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?