/******************************************************************************
Online C++ Compiler.
Code, Compile, Run and Debug C++ program online.
Write your code in this editor and press "Run" button to compile and execute it.
*******************************************************************************/
#include <iostream>
using namespace std;
class Parent
{
public:
virtual void call() {
// void call() {
printf("Hello Parent!\n");
}
};
class Child : public Parent {
public:
void call(){
printf("Hello Child!\n");
}
};
class Child2 : public Parent {
public:
void call(){
printf("Hello Child2!\n");
}
};
void importer(Parent* child){
child->call();
}
int main()
{
// Parent *A; // 가능
// Parent *A = new Parent(); //에러
Parent* A = new Child();
Parent* B = new Child2();
importer(A);
importer(B);
Child* C = new Child();
Child2* D = new Child2();
importer(C);
importer(D);
printf("Done.\n");
return 0;
}
.LC0:
.ascii "Hello Parent!\000"
Parent::call():
push {r7, lr}
sub sp, sp, #8
add r7, sp, #0
str r0, [r7, #4]
movw r0, #:lower16:.LC0
movt r0, #:upper16:.LC0
bl puts
nop
adds r7, r7, #8
mov sp, r7
pop {r7, pc}
.LC1:
.ascii "Hello Child!\000"
Child::call():
push {r7, lr}
sub sp, sp, #8
add r7, sp, #0
str r0, [r7, #4]
movw r0, #:lower16:.LC1
movt r0, #:upper16:.LC1
bl puts
nop
adds r7, r7, #8
mov sp, r7
pop {r7, pc}
.LC2:
.ascii "Hello Child2!\000"
Child2::call():
push {r7, lr}
sub sp, sp, #8
add r7, sp, #0
str r0, [r7, #4]
movw r0, #:lower16:.LC2
movt r0, #:upper16:.LC2
bl puts
nop
adds r7, r7, #8
mov sp, r7
pop {r7, pc}
importer(Parent*):
push {r7, lr}
sub sp, sp, #8
add r7, sp, #0
str r0, [r7, #4]
ldr r3, [r7, #4]
ldr r3, [r3]
ldr r3, [r3]
ldr r0, [r7, #4]
blx r3
nop
adds r7, r7, #8
mov sp, r7
pop {r7, pc}
Parent::Parent() [base object constructor]:
push {r7}
sub sp, sp, #12
add r7, sp, #0
str r0, [r7, #4]
ldr r2, .L7
ldr r3, [r7, #4]
str r2, [r3]
ldr r3, [r7, #4]
mov r0, r3
adds r7, r7, #12
mov sp, r7
ldr r7, [sp], #4
bx lr
.L7:
.word vtable for Parent+8
Child::Child() [base object constructor]:
push {r7, lr}
sub sp, sp, #8
add r7, sp, #0
str r0, [r7, #4]
ldr r3, [r7, #4]
mov r0, r3
bl Parent::Parent() [base object constructor]
ldr r2, .L11
ldr r3, [r7, #4]
str r2, [r3]
ldr r3, [r7, #4]
mov r0, r3
adds r7, r7, #8
mov sp, r7
pop {r7, pc}
.L11:
.word vtable for Child+8
Child2::Child2() [base object constructor]:
push {r7, lr}
sub sp, sp, #8
add r7, sp, #0
str r0, [r7, #4]
ldr r3, [r7, #4]
mov r0, r3
bl Parent::Parent() [base object constructor]
ldr r2, .L15
ldr r3, [r7, #4]
str r2, [r3]
ldr r3, [r7, #4]
mov r0, r3
adds r7, r7, #8
mov sp, r7
pop {r7, pc}
.L15:
.word vtable for Child2+8
.LC3:
.ascii "Done.\000"
main:
push {r4, r7, lr}
sub sp, sp, #12
add r7, sp, #0
movs r0, #4
bl operator new(unsigned int)
mov r3, r0
mov r4, r3
movs r3, #0
str r3, [r4]
mov r0, r4
bl Child::Child() [complete object constructor]
str r4, [r7, #4]
movs r0, #4
bl operator new(unsigned int)
mov r3, r0
mov r4, r3
movs r3, #0
str r3, [r4]
mov r0, r4
bl Child2::Child2() [complete object constructor]
str r4, [r7]
ldr r0, [r7, #4]
bl importer(Parent*)
ldr r0, [r7]
bl importer(Parent*)
movw r0, #:lower16:.LC3
movt r0, #:upper16:.LC3
bl puts
movs r3, #0
mov r0, r3
adds r7, r7, #12
mov sp, r7
pop {r4, r7, pc}
vtable for Child2:
.word 0
.word typeinfo for Child2
.word Child2::call()
vtable for Child:
.word 0
.word typeinfo for Child
.word Child::call()
vtable for Parent:
.word 0
.word typeinfo for Parent
.word Parent::call()
typeinfo for Child2:
.word _ZTVN10__cxxabiv120__si_class_type_infoE+8
.word typeinfo name for Child2
.word typeinfo for Parent
typeinfo name for Child2:
.ascii "6Child2\000"
typeinfo for Child:
.word _ZTVN10__cxxabiv120__si_class_type_infoE+8
.word typeinfo name for Child
.word typeinfo for Parent
typeinfo name for Child:
.ascii "5Child\000"
typeinfo for Parent:
.word _ZTVN10__cxxabiv117__class_type_infoE+8
.word typeinfo name for Parent
typeinfo name for Parent:
.ascii "6Parent\000"
__static_initialization_and_destruction_0(int, int):
push {r7, lr}
sub sp, sp, #8
add r7, sp, #0
str r0, [r7, #4]
str r1, [r7]
ldr r3, [r7, #4]
cmp r3, #1
bne .L21
ldr r3, [r7]
movw r2, #65535
cmp r3, r2
bne .L21
movw r0, #:lower16:_ZStL8__ioinit
movt r0, #:upper16:_ZStL8__ioinit
bl std::ios_base::Init::Init() [complete object constructor]
movw r2, #:lower16:__dso_handle
movt r2, #:upper16:__dso_handle
movw r1, #:lower16:_ZNSt8ios_base4InitD1Ev
movt r1, #:upper16:_ZNSt8ios_base4InitD1Ev
movw r0, #:lower16:_ZStL8__ioinit
movt r0, #:upper16:_ZStL8__ioinit
bl __aeabi_atexit
.L21:
nop
adds r7, r7, #8
mov sp, r7
pop {r7, pc}
_GLOBAL__sub_I_importer(Parent*):
push {r7, lr}
add r7, sp, #0
movw r1, #65535
movs r0, #1
bl __static_initialization_and_destruction_0(int, int)
pop {r7, pc}
보다시피 Child::call() 에 대한 라벨이 제작됨을 알 수 있다.
/******************************************************************************
Online C++ Compiler.
Code, Compile, Run and Debug C++ program online.
Write your code in this editor and press "Run" button to compile and execute it.
*******************************************************************************/
#include <iostream>
using namespace std;
class Parent
{
public:
// virtual void call() {
void call() {
printf("Hello Parent!\n");
}
};
class Child : public Parent {
public:
void call(){
printf("Hello Child!\n");
}
};
class Child2 : public Parent {
public:
void call(){
printf("Hello Child2!\n");
}
};
void importer(Parent* child){
child->call();
}
int main()
{
// Parent *A; // 가능
// Parent *A = new Parent(); //에러
Parent* A = new Child();
Parent* B = new Child2();
importer(A);
importer(B);
Child* C = new Child();
Child2* D = new Child2();
importer(C);
importer(D);
printf("Done.\n");
return 0;
}
.LC0:
.ascii "Hello Parent!\000"
Parent::call():
push {r7, lr}
sub sp, sp, #8
add r7, sp, #0
str r0, [r7, #4]
movw r0, #:lower16:.LC0
movt r0, #:upper16:.LC0
bl puts
nop
adds r7, r7, #8
mov sp, r7
pop {r7, pc}
importer(Parent*):
push {r7, lr}
sub sp, sp, #8
add r7, sp, #0
str r0, [r7, #4]
ldr r0, [r7, #4]
bl Parent::call()
nop
adds r7, r7, #8
mov sp, r7
pop {r7, pc}
.LC1:
.ascii "Done.\000"
main:
push {r7, lr}
sub sp, sp, #8
add r7, sp, #0
movs r0, #1
bl operator new(unsigned int)
mov r3, r0
str r3, [r7, #4]
movs r0, #1
bl operator new(unsigned int)
mov r3, r0
str r3, [r7]
ldr r0, [r7, #4]
bl importer(Parent*)
ldr r0, [r7]
bl importer(Parent*)
movw r0, #:lower16:.LC1
movt r0, #:upper16:.LC1
bl puts
movs r3, #0
mov r0, r3
adds r7, r7, #8
mov sp, r7
pop {r7, pc}
__static_initialization_and_destruction_0(int, int):
push {r7, lr}
sub sp, sp, #8
add r7, sp, #0
str r0, [r7, #4]
str r1, [r7]
ldr r3, [r7, #4]
cmp r3, #1
bne .L7
ldr r3, [r7]
movw r2, #65535
cmp r3, r2
bne .L7
movw r0, #:lower16:_ZStL8__ioinit
movt r0, #:upper16:_ZStL8__ioinit
bl std::ios_base::Init::Init() [complete object constructor]
movw r2, #:lower16:__dso_handle
movt r2, #:upper16:__dso_handle
movw r1, #:lower16:_ZNSt8ios_base4InitD1Ev
movt r1, #:upper16:_ZNSt8ios_base4InitD1Ev
movw r0, #:lower16:_ZStL8__ioinit
movt r0, #:upper16:_ZStL8__ioinit
bl __aeabi_atexit
.L7:
nop
adds r7, r7, #8
mov sp, r7
pop {r7, pc}
_GLOBAL__sub_I_importer(Parent*):
push {r7, lr}
add r7, sp, #0
movw r1, #65535
movs r0, #1
bl __static_initialization_and_destruction_0(int, int)
pop {r7, pc}
보다시피, 애초에 아예 Child::call() 이라는 라벨자체가 만들어지지 않는다.
즉, virtual 키워드 없는 부모메소드는 자식에서 오버라이딩이 "불가함" 을 알 수 있다.