Accessing post->ID outside of the loop for listing child pages

… the post->ID won’t return anything if it’s before the loop

Generally speaking, this is false. The $post variable is set well before the Loop starts in your theme, for most pages. The main query “primes” that variable to the first post in the Loop. That said, depending on this variable outside the Loop is not the most reliable approach. More reliable, would be to use get_queried_object.

$qobj = get_queried_object();
wp_list_pages('title_li=&child_of=".$qobj->ID);

Because get_queried_object returns different information depending on the page you are on, you are also better off checking for the page type before using it.

if (is_page()) {
    $qobj = get_queried_object();
    wp_list_pages("title_li=&child_of=".$qobj->ID);
}

Or check the object itself.

$qobj = get_queried_object();
if (isset($qobj->post_type) && "page' == $qobj->post_type) {
  wp_list_pages('title_li=&child_of=".$qobj->ID);
}

Those are just examples. I don”t know what your precise conditions are.